2014-07-19 3 views
9

Così ho un personalizzato modello Binder implementato per DateTime tipo e mi registrarlo come di seguito:Web API ModelBinding Da URI

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

e poi devo configurazione 2 azioni campione per vedere se il mio modello personalizzato avviene il legame :

[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 eseguo e invoco entrambe le azioni da URL citati, user 's JoinDate proprietà con successo viene legato usando il legante personalizzato ho configurato ma BindDateTime' sIl parametronon viene associato utilizzando il raccoglitore personalizzato.

Ho già specificato in config che tutti gli DateTime devono 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 uso [FromUri(Binder=typeof(CurrentCultureDateTimeAPI))]DateTime datetime allora funziona come previsto, ma poi di nuovo perché?

+1

Forse questo è perché si sta impostando un [FromUri] attributo - Web API utilizza formattatori al posto del modello vincolanti, così il vostro il raccoglitore modello personalizzato non viene utilizzato.Prova a rimuovere l'attributo [FromUri] nel metodo BindDateTime. –

+0

@IlyaLuzyanin No. Non funziona. – lbrahim

+0

Hai ragione, [FromUri] non ha nulla a che fare con questo. Ho provato a riprodurre il tuo scenario: tutto funziona perfettamente, il mio modello personalizzato è chiamato in entrambi i metodi. Potresti fornire il codice CurrentCultureDateTimeAPI? –

risposta

5

Abbastanza sorprendente troppo :)

Il mio dubbio iniziale era questa linea:

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

MSDN dice 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.

Quindi,

Basta aggiungere questa linea all'interno della classe statica WebApiConfig

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

in modo che il file WebAPIConfig assomiglia:

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 è direttamente invocato da WebAPI framework quindi sicuramente il tuo CurrentCultureDateTimeAPI viene registrato.

Controllato questo con la soluzione e funziona benissimo.

Nota: (Dai commenti) È ancora possibile sostenere Attribute Routing e non c'è bisogno di commentare questa linea config.MapHttpAttributeRoutes().

Ma ancora, sarebbe bello se qualcuno può dire perché GlobalConfiguration non dovesse funzionare

-5

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.