【发布时间】:2018-10-30 11:57:23
【问题描述】:
考虑以下示例:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace WebApiApp.Controllers
{
public class TheModelFields
{
public int Id { get; set; }
}
[ModelBinder(typeof(TheModelBinder))]
public class TheModel
{
public PropertyInfo PropInfo { get; set; }
public PropertyInfo FieldPropInfo;
public object BoxedPropInfo { get; set; }
}
enum TestMode
{
PropInfo,
FieldPropInfo,
BoxedPropInfo
}
public class TheModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext.HttpContext.Request.Query.TryGetValue("testMode", out var modeStr) && Enum.TryParse(typeof(TestMode), modeStr, true, out var mode))
{
var model = new TheModel();
var propInfo = typeof(TheModelFields).GetProperty("Id");
switch (mode)
{
case TestMode.PropInfo:
model.PropInfo = propInfo;
break;
case TestMode.FieldPropInfo:
model.FieldPropInfo = propInfo;
break;
case TestMode.BoxedPropInfo:
model.BoxedPropInfo = propInfo;
break;
}
bindingContext.Result = ModelBindingResult.Success(model);
Timer.Stopwatch.Restart();
return Task.CompletedTask;
}
else
{
bindingContext.Result = ModelBindingResult.Failed();
return Task.CompletedTask;
}
}
}
public static class Timer
{
public static Stopwatch Stopwatch = new Stopwatch();
}
[ApiController]
public class TestController : ControllerBase
{
[HttpGet("test")]
public IActionResult Test([FromQuery]TheModel model)
{
Timer.Stopwatch.Stop();
if (model is null)
return BadRequest("pass testMode=PropInfo|FieldPropInfo|BoxedPropInfo for test");
else
return Ok($"Time: {Timer.Stopwatch.ElapsedMilliseconds}");
}
}
}
TheModel 类有一个名为 TheModelBinder 的自定义 ModelBinder。
在这个测试中,TheModelBinder 根据名为 testMode 的查询字符串参数的值来决定设置什么属性/字段。
使用静态秒表,我开始测量模型绑定结束和动作开始之间的时间。以下是大致结果:
如果testMode == PropInfo 则TheModelBinder 将值设置为PropertyInfo 类型的属性,名为PropInfo。
(这很慢,大约 800-1000 毫秒)
如果 testMode == FieldPropInfo 则 TheModelBinder 将值设置为类型为 PropertyInfo 的字段,名为 PropInfoField。
(这个需要0ms)
如果testMode == BoxedPropInfo 则TheModelBinder 将值设置为名为@987654336@ 的对象类型的属性。
(这个也需要0ms)
现在的问题是:为什么第一个 testMode(设置PropInfo 属性)会将执行时间(模型绑定成功后)增加到 800-1000 毫秒?
在 asp.net core 2.1 和 2.2 preview2 上测试
要自己测试,您可以执行dotnet new webapi 并将示例内容粘贴到新文件中。如果您在端口 5000 上运行应用程序,您可以使用这些 URL 测试执行时间:
http://localhost:5000/test?testMode=propInfohttp://localhost:5000/test?testMode=propInfoFieldhttp://localhost:5000/test?testMode=boxedPropInfo
【问题讨论】:
标签: c# asp.net-core