建模绑定永远

Modeling binding taking forever

我有一个 UserFilter class 作为 Web API 2 操作方法的参数,它需要约 30 秒才能完成绑定。我已经在创建 UserFilter class 时进入了它,它根本不需要时间来实例化,但是一旦它创建了 Web API 就在后台做一些事情来解释 ~ 30 秒,然后终于开始执行我的操作方法。

我在同一个项目中的 MVC 控制器上设置了 UserFilter,它立即绑定,没有延迟。只有 Web API 有这个问题。


我怎样才能弄清楚 Web API 在后台做什么?

绑定生命周期中是否有我可以锁定的事件?

[Route("all")]
[HttpPost]
public async Task<IHttpActionResult> GetUsers([FromBody]UserFilter filter)
{
    // takes ~30 seconds before a breakpoint hits this next line
    filter = UserFilter.InitializeFilter(filter);

    var userList = await UserRepository.GetUsers(filter).ConfigureAwait(false);
    return Ok(new JsonResponse(new { Users = userList, Pager = filter.Pager }));
}

public class UserFilter : BaseFilter<UserFilter, User>
{
    // DO NOT REMOVE: default constructor needed for model binding
    public UserFilter() : base() { }

    public UserFilter(int? pageSize)
        : base(pageSize)
    {
    }
    ...
}

public abstract class BaseFilter<TFilterType, TEntity>
{
    // default constructor needed for model binding
    public BaseFilter()
    {
        Pager = new Pager(null);
        Init();
    }

    public BaseFilter(int? pageSize)
    {
        Pager = new Pager(pageSize);
        Init();
    }
    ...
}

原来是 Web API 2 模型绑定代码的问题。 class QueryMutatorCondition 有一个以泛型 Predicate<>Func<> 作为参数的构造函数。这就是 Web API 令人窒息的原因。

出于未知原因,它继续尝试绑定到 QueryMutators 属性(BaseFilter class 的成员),即使我告诉它忽略它属性。修复是将访问修饰符更改为 internal 而不是 public 以防止 Web API 尝试绑定到它。

[JsonIgnore]
public List<QueryMutatorCondition<TFilterType, TEntity>> QueryMutators { get; set; }

变成了:

internal List<QueryMutatorCondition<TFilterType, TEntity>> QueryMutators { get; set; }