在Web API中未发布数据时,请避免使用null模型

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

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

但它没有得到回答。

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

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

该模型使用动作filter中的其他数据填充。

在这种情况下,所有需要知道的是UserId,动作filter将基于cookie /标头添加到模型中,并与请求一起传入。

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

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

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

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

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

您可以在动作filter中执行以下操作。 仅当您的模型包含默认构造函数时,以下代码才有效。

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); } 

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); } 

@ Sarathy的解决方案有效,但不会触发它创建的对象的模型validation。 这可能导致将空模型传递给操作但ModelState.IsValid仍然计算为true的情况。

出于我自己的目的,有必要在创建空模型对象的情况下触发模型的重新validation:

  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 = Activator.CreateInstance(parameter.ParameterType); actionContext.ActionArguments[parameter.ParameterName] = value; var bodyModelValidator = actionContext.ControllerContext.Configuration.Services.GetBodyModelValidator(); var metadataProvider = actionContext.ControllerContext.Configuration.Services.GetModelMetadataProvider(); bodyModelValidator.Validate(value, value.GetType(), metadataProvider, actionContext, string.Empty); } base.OnActionExecuting(actionContext); }