API Web ModelBinding dall’URI

Quindi ho implementato un Model Binder personalizzato per tipo DateTime e lo registro come di seguito:

 void Application_Start(object sender, EventArgs e) { // Code that runs on application startup GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI()); } 

e quindi ho impostato 2 azioni di esempio per verificare se il binding del modello personalizzato ha luogo:

  [HttpGet] public void BindDateTime([FromUri]DateTime datetime) { //http://localhost:26171/web/api/BindDateTime?datetime=09/12/2014 } [HttpGet] public void BindModel([FromUri]User user) { //http://localhost:26171/web/api/BindModel?Name=ibrahim&JoinDate=09/12/2014 } 

Quando JoinDate e invoco entrambe le azioni dagli URL menzionati, user proprietà JoinDate user viene vincasting correttamente utilizzando il raccoglitore personalizzato che ho configurato, ma il parametro datetime BindDateTime non viene associato utilizzando il raccoglitore personalizzato.

Ho già specificato in config che DateTime dovrebbe utilizzare il mio raccoglitore personalizzato e quindi perché l’indifferenza? I suggerimenti sono molto apprezzati.

CurrentCultureDateTimeAPI.cs:

 public class CurrentCultureDateTimeAPI: IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); var date = value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture); bindingContext.Model = date; return true; } } 

NOTA: Se utilizzo [FromUri(Binder=typeof(CurrentCultureDateTimeAPI))]DateTime datetime allora funziona come previsto ma, di nuovo, perché?

Abbastanza sorprendente 🙂

Il mio dubbio iniziale era questa linea:

  GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI()); 

MSDN afferma che GlobalConfiguration => GlobalConfiguration provides a global System.Web.HTTP.HttpConfiguration for ASP.NET application .

Ma per motivi strani questo non sembra funzionare con questo particolare scenario.

Così,

Basta aggiungere questa riga all’interno della class statica WebApiConfig

  config.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI()); 

così che il tuo file WebAPIConfig assomiglia a:

  public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "web/{controller}/{action}/{datetime}", defaults: new { controller = "API", datetime = RouteParameter.Optional } ); config.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI()); } 

E tutto funziona bene perché questo metodo viene richiamato direttamente dal WebAPI framework quindi sicuramente CurrentCultureDateTimeAPI viene registrato.

Controllato con la tua soluzione e funziona alla grande.

Nota: (Dai commenti) È ancora ansible supportare l’ Attribute Routing e non è necessario commentare questa riga config.MapHttpAttributeRoutes() .

Ma ancora, sarebbe bello se qualcuno potesse dire perché GlobalConfiguration non funziona

Sembra che tu voglia pubblicare alcuni dati sul server. Prova a utilizzare FromData e post JSON. FromUri viene in genere utilizzato per recuperare alcuni dati. Utilizza le convenzioni di WebAPI e consenti che funzioni per te.