【问题标题】:IModelBinder DelayIModelBinder 延迟
【发布时间】:2019-04-04 01:59:31
【问题描述】:

我创建了使用接口作为 post 参数的控制器。由于参数是一个接口,我使用 IModelBinder 将 request.Body 转换为 IQuery 对象。 IModelBinder解析没有问题,在Controller上执行也没有问题。我得到的唯一问题是 request.Body 被解析为 IQuery 对象直到在 Controller body 上收到之前存在延迟。

我用来解析请求正文的 IModelBinder:

public Task BindModelAsync(ModelBindingContext bindingContext)
{
    string _queryJson = String.Empty;
    try
    {
        StreamReader _reader = new StreamReader(bindingContext.HttpContext.Request.Body);
        _queryJson = _reader.ReadToEnd();
        if (_queryJson.IsEmpty())
        {
            bindingContext.Result = ModelBindingResult.Failed();
            goto done;
        }
    }
    catch
    {
        bindingContext.Result = ModelBindingResult.Failed();
        goto done;
    }

    bindingContext.Result = ModelBindingResult.Success(QueryBuilder.ParseJson(DataContext, _queryJson));
    System.Diagnostics.Trace.WriteLine($"QUERY PARSING COMPLETE {DateTime.Now.ToString("HH:mm:ss.fffffff")}");
    done:
    return Task.CompletedTask;
}

控制器:

[HttpPost]
public IActionResult Query(IQuery query)
{
    try
    {
        System.Diagnostics.Trace.WriteLine($"QUERY ON CONTROLLER {DateTime.Now.ToString("HH:mm:ss.fffffff")}");
        query.ThrowArgumentNullException("query", "Missing query to execute");
        if (query is ISelectQuery)
        {
            var _rows = ((ISelectQuery)query)
                .ReadAll()
                .ToArray();
            return new EntitiesResult(((ISelectQuery)query).ViewEntity, _rows.Length, _rows);
        }
        else
            throw new InvalidCastException($"Only select query can be executed for now");
    }
    catch (Exception ex) { return new ExceptionResult(ex); }
}

正如上面的代码,我使用 Trace 来跟踪 IQuery 对象何时完成解析以及 Controller 何时收到 IQuery 对象。我查看输出窗口,发现在控制器上解析和接收后有 10+s 的延迟。 output

我认为这可能与日志记录有关,所以我在启动时禁用了日志记录:

services.AddLogging(builder =>
{
    builder.AddFilter("Microsoft", LogLevel.None)
                 .AddFilter("System", LogLevel.None)
                 .AddFilter("NToastNotify", LogLevel.None)
                 .AddConsole();
});

结果还是有延迟,对IQuery对象的ToString方法的调用还是被调用disabled

呼叫请求示例:postman

我没有找到 ASP.Net Core ModelBindingContext 的源代码或任何源代码,所以我不知道是什么导致对象在被绑定器解析并在控制器上接收后延迟。

【问题讨论】:

    标签: imodelbinder


    【解决方案1】:

    发现问题。在阅读 ParameterBinder 的源代码并启用登录到 Trace 模式后,我发现原因是 ObjectModelValidator。在我的活页夹完成解析后,验证器会启动并验证我的 IQuery。这会导致ParameterBinder 上的延迟

    为了解决这个问题,我使用了 Skorunka František 在disable validator 上给出的临时解决方案

    现在我只需要找到只为我的特定 IModelBinder 禁用验证器的方法

    【讨论】:

      猜你喜欢
      • 2017-07-28
      • 1970-01-01
      • 2019-06-07
      • 2015-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多