我正在使用Web 5构建Web,我通过扩展IModelBinder接口来将复杂类型映射为要操作的参数,从而实现自定义模型绑定。装订部份运作良好。但是模型验证没有发生。ModelState.IsValid总是正确的。
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<NewsItemVM> 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<NewsItemVM> Get([FromUri]PagingParamsVM pegination)
{
var valid = ModelState.IsValid;
}
应该在模型活页夹内实现验证部分。如果是这样的话,我应该如何实现?
发布于 2016-12-05 03:55:30
我找到了答案。可以在自定义模型绑定器中调用默认验证过程,如下所示,
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;
}
}
谢谢你们的支持。
发布于 2016-12-04 23:47:01
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<NewsItemVM> 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<NewsItemVM>();
}
}
https://stackoverflow.com/questions/40968811
复制相似问题