Web APIvalidation不会触发自定义模型绑定器

我正在使用Web API 5构建Web服务。我正在通过扩展IModelBinder接口来实现自定义模型绑定器,以将复杂类型映射为动作参数。 绑定部分工作正常。 但模型validation不会发生。 ModelState.IsValid始终为true。

public class PagingParamsVM { [Range(1, Int32.MaxValue, ErrorMessage = "Page must be at least 1")] public int? Page { get; set; } [Range(1, Int32.MaxValue, ErrorMessage = "Page size must be at least 1")] public int? PageSize { get; set; } } public class PaginationModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { var model = (PagingParamsVM)bindingContext.Model ?? new PagingParamsVM(); //model population logic ..... bindingContext.Model = model; return true; } } public IEnumerable Get([ModelBinder(typeof(PaginationModelBinder))]PagingParamsVM pegination) { //Validate(pegination); //if I call this explicitly ModelState.IsValid is set correctly. var valid = ModelState.IsValid; //this is always true } public class ModelStateValidationActionFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var valid = actionContext.ModelState.IsValid //this is always true. } } 

如果我显式调用Validate()或使用[FromUri]属性,则正确设置ModelState.IsValid。

 public IEnumerable Get([FromUri]PagingParamsVM pegination) { var valid = ModelState.IsValid; } 

我应该在模型绑定器中实现validation部分。 如果是这样我应该如何实施?

我找到了答案。 可以在自定义模型绑定器中调用默认validation过程,如下所示,

 public abstract class PaginationModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { var model = (PagingParamsVM)bindingContext.Model ?? new PagingParamsVM(); //model population logic ..... bindingContext.Model = model; //following lines invoke default validation on model bindingContext.ValidationNode.ValidateAllProperties = true; bindingContext.ValidationNode.Validate(actionContext); return true; } } 

谢谢你们的支持。

DefaultModelBinder.CreateModel应该可以帮助您保持模型状态:

 public class PaginationModelBinder : DefaultModelBinder { protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { if(modelType == typeof(PagingParamsVM)) { var page = default(int?); var model = bindingContext.Model; var valueProvider = bindingContext.ValueProvider; var pageValue = valueProvider.GetValue("Page"); var tmp = default(int); if(pageValue != null && int.TryParse(pageValue.AttemptedValue, out tmp)) { page = tmp; } var pageSize = default(int?); var sizeValue = valueProvider.GetValue("PageSize"); if(sizeValue != null && int.TryParse(sizeValue.AttemptedValue, out tmp)) { pageSize = tmp; } return new PagingParamsVM { Page = page, PageSize = pageSize }; } return base.CreateModel(controllerContext, bindingContext, modelType); } } 

使用活页夹的web api控制器可以是:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; public class NewsItemController : ApiController { public IEnumerable Get([ModelBinder(typeof(PaginationModelBinder))]PagingParamsVM pegination) { //Validate(pegination); //if I call this explicitly ModelState.IsValid is set correctly. var valid = ModelState.IsValid; //this is always true return Enumerable.Empty(); } }