ASP.NET Web API Model Binding

I use the web API in ASP.NET MVC 4 RC, and I have a method that accepts a complex object with null DateTime properties. I want input values ​​to be read from the query string, so I have something like this:

public class MyCriteria { public int? ID { get; set; } public DateTime? Date { get; set; } } [HttpGet] public IEnumerable<MyResult> Search([FromUri]MyCriteria criteria) { // Do stuff here. } 

This works well if I pass the standard date format in the query string, such as 01/15/2012:

 http://mysite/Search?ID=1&Date=01/15/2012 

However, I want to specify a custom format for DateTime (possibly MMddyyyy) ... for example:

 http://mysite/Search?ID=1&Date=01152012 

Edit:

I tried to apply custom model binding, but I could not apply it only to DateTime objects. The ModelBinderProvider I tried looks something like this:

 public class DateTimeModelBinderProvider : ModelBinderProvider { public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(DateTime) || bindingContext.ModelType == typeof(DateTime?)) { return new DateTimeModelBinder(); } return null; } } // In the Global.asax GlobalConfiguration.Configuration.Services.Add(typeof(ModelBinderProvider), new DateTimeModelBinderProvider()); 

A new middleware provider has been created, but GetBinder is called only once (for a complex model parameter, but not for each property in the model). This makes sense, but I would like to find a way to use it for DateTimeModelBinder properties for DateTime using the default binding for non-DateTime properties. Is there a way to override the default ModelBinder and indicate how each property is bound?

Thanks!!!

+6
source share
1 answer

Consider setting the Date property for the view model: string

Then, either write a utility function to handle the mapping between the type of the view model and the type of domain model:

 public static MyCriteria MapMyCriteriaViewModelToDomain(MyCriteriaViewModel model){ var date = Convert.ToDateTime(model.Date.Substring(0,2) + "/" model.Date.Substring(2,2) + "/" model.Date.Substring(4,2)); return new MyCriteria { ID = model.ID, Date = date }; } 

or use a tool like AutoMapper , for example:

at Global.asax

 //if passed as MMDDYYYY: Mapper.CreateMap<MyCriteriaViewModel, MyCriteria>(). .ForMember( dest => dest.Date, opt => opt.MapFrom(src => Convert.ToDateTime(src.Date.Substring(0,2) + "/" src.Date.Substring(2,2) + "/" src.Date.Substring(4,2))) ); 

and in the controller:

 public ActionResult MyAction(MyCriteriaViewModel model) { var myCriteria = Mapper.Map<MyCriteriaViewModel, MyCriteria>(model); // etc. } 

In this example, AutoMapper might not seem to provide any added value. This value occurs when you configure several or more mappings to objects that usually have more properties than this example. CreateMap automatically maps properties to the same name and type, so it saves a lot of input and a lot of DRYer.

+1
source

Source: https://habr.com/ru/post/922433/


All Articles