Я создал контроллер, который использует интерфейс в качестве параметра post. Поскольку параметр интерфейс, я использую IModelBinder, чтобы перевести request.Body в объект IQuery. Синтаксический анализ IModelBinder не имеет проблем, и выполнение на контроллере также не имеет проблем. Единственная проблема, с которой я столкнулся, - это задержка запроса. Когда он анализируется в объекте IQuery, его получают в теле контроллера.
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 завершит анализ и когда контроллер получит объект IQuery. Я заглянул в окно вывода и обнаружил, что после анализа и получения на контроллере задержка составляет 10 с.
выход
Я подумал, что это может быть связано с ведением журнала, поэтому я отключаю ведение журнала при запуске:
services.AddLogging(builder =>
{
builder.AddFilter("Microsoft", LogLevel.None)
.AddFilter("System", LogLevel.None)
.AddFilter("NToastNotify", LogLevel.None)
.AddConsole();
});
В результате все еще сохраняется задержка, и вызов метода ToString объекта IQuery все еще вызывается отключен
Пример запроса звонка: почтальон
Я не нашел исходный код для ASP.Net Core ModelBindingContext или какой-либо другой, поэтому я понятия не имел, что вызывает задержку объекта после анализа связывателем и получения на контроллере.