I have created controller that use an interface as the post parameter. Since the parameter an interface I use IModelBinder to translate the request.Body into IQuery object. The parsing by IModelBinder has no issue, and execution on Controller also have no issue. The only issue that I got is that there's a delay from the request.Body being parsed into IQuery object till get received on Controller body.
The IModelBinder that I use to parse the request body:
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;
}
The controller:
[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); }
}
As the code above I put Trace to track when the IQuery object finish parsed and when the Controller receive the IQuery object. I look into the output window and found that after being parsed and received on controller there's a 10+s delay. output
I thought this might related to Logging, so I disable the logging on the start up:
services.AddLogging(builder =>
{
builder.AddFilter("Microsoft", LogLevel.None)
.AddFilter("System", LogLevel.None)
.AddFilter("NToastNotify", LogLevel.None)
.AddConsole();
});
The result still there's delay and the call to ToString method of IQuery object still being called disabled
Call request example : postman
I didn't found the source code for ASP.Net Core ModelBindingContext or any so I didn't have clue what cause the object delay after being parsed by binder and received on controller.