在 Web API 中没有发布数据时避免空模型

Phi*_*ill 5 c# asp.net-web-api

这个问题类似于我想要实现的目标:

当没有发布的属性与模型匹配时,避免在 ASP.Net Web API 中使用空模型

但它没有得到答复。

我有一个采用 GET 模型的路线:

    [HttpGet, Route("accounts")]
    public AccountListResult Post(AccountListRequest loginRequest)
    {
        return accountService.GetAccounts(loginRequest);
    }
Run Code Online (Sandbox Code Playgroud)

该模型填充有来自操作过滤器的附加数据。

在这种情况下,所有需要知道的是 UserId,动作过滤器根据 cookie/header 将其添加到模型中,并与请求一起传入。

我想在 WebAPI 中使用所有默认模型绑定,但我想避免空对象。

我不相信模型绑定可以解决我的问题。

如何替换 Web API 模型绑定的行为,以便在没有传入参数时接收新实例而不是 Null

这更接近我想要做的,除了它的每种类型很乏味。

Sar*_*thy 5

编辑:由于问题是针对 Web API 的,我也在下面发布了 Web API 解决方案。

您可以在操作过滤器中按如下方式执行此操作。以下代码仅在您的模型包含默认构造函数时才有效。

Web API 实现:

public override void OnActionExecuting(HttpActionContext actionContext)
{
     var parameters = actionContext.ActionDescriptor.GetParameters();

     foreach (var parameter in parameters)
     {
         object value = null;

         if (actionContext.ActionArguments.ContainsKey(parameter.ParameterName))
             value = actionContext.ActionArguments[parameter.ParameterName];

         if (value != null)
            continue;

         value = CreateInstance(parameter.ParameterType);
         actionContext.ActionArguments[parameter.ParameterName] = value;
     }

     base.OnActionExecuting(actionContext);
}

protected virtual object CreateInstance(Type type)
{
   // Check for existence of default constructor using reflection if needed
   // and if performance is not a constraint.

   // The below line will fail if the model does not contain a default constructor.
   return Activator.CreateInstance(type);
}
Run Code Online (Sandbox Code Playgroud)

MVC 实现:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var parameters = filterContext.ActionDescriptor.GetParameters();

    foreach (var parameter in parameters)
    {
        if (filterContext.ActionParameters.ContainsKey(parameter.ParameterName))
        {
            object value = filterContext.ActionParameters[parameter.ParameterName];

            if (value == null)
            {
                 // The below line will fail if the model does not contain a default constructor.
                 value = Activator.CreateInstance(parameter.ParameterType);                          
                 filterContext.ActionParameters[parameter.ParameterName] = value;
            }
        }                
    }

    base.OnActionExecuting(filterContext);
}
Run Code Online (Sandbox Code Playgroud)