I'm building Web Service with Web API 5. I'm implementing custom model binder by extending IModelBinder interface to map complex type as a parameter to action. The binding part is working fine. But Model validation does not occur. ModelState.IsValid is always 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<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.
}
}
If I call Validate() explicitly or use [FromUri] attribute, ModelState.IsValid is set correctly.
public IEnumerable<NewsItemVM> Get([FromUri]PagingParamsVM pegination)
{
var valid = ModelState.IsValid;
}
Should I implement validation part inside model binder. If so how should I implement?
ModelState. IsValid indicates if it was possible to bind the incoming values from the request to the model correctly and whether any explicitly specified validation rules were broken during the model binding process.
The state of the submitted Model is checked using ModelState. IsValid property and if the Model is valid then the value of the Name property is set in a ViewBag object.
In short, the ModelState is a collection of name and value pairs that are submitted to the server during a POST. It also contains error messages about each name-value pair, if any are found. ModelState is a property of a Controller instance, and can be accessed from any class that inherits from Microsoft.
I found an answer. The default validation process can be invoked in custom model binder as follows,
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;
}
}
Thank you guys for your support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With