2013-07-10 17 views
8

Voglio inviare un oggetto complesso con un array nidificato in uri a un metodo di azione MVC in una richiesta GET.Usando [FromUri] attributo - legano oggetto complesso con array nidificato

Si consideri il seguente codice:

public ActionResult AutoCompleteHandler([FromUri]PartsQuery partsQuery){ ... } 

public class PartsQuery 
{ 
    public Part[] Parts {get; set; } 
    public string LastKey { get; set; } 
    public string Term { get; set; } 
} 

$.ajax({ 
    url: "Controller/AutoCompleteHandler", 
    data: $.param({           
         Parts: [{ hasLabel: "label", hasType: "type", hasIndex : 1 }], 
         LastKey : "Last Key", 
         Term : "Term"        
        }), 
    dataType: "json", 
    success: function(jsonData) { ... } 
}); 

Questo funziona bene e si lega in modo corretto utilizzando il legante modello predefinito in MVC Web Api.

Tuttavia, passare questo semplice MVC non WebAPI e le pause legante modello predefinito verso il basso e non possono vincolare la proprietà sugli oggetti nella matrice nidificato:

selezione

partsQuery  != null   //Good 
--LastKey  == "Last Key" //Good 
--Term   == "Term"  //Good 
--Parts[]  != null   //Good 
----hasLabel == null   //Failed to bind 
----hasType  == null   //Failed to bind 
----hasIndex == 0    //Failed to bind 

Vorrei sapere perché questo si rompe in pianura MVC e come fare FromUriAttribute legano questo oggetto correttamente in pianura MVC

+0

Cosa succede se si cambia 'Parte [] Parti' in' Parti ICollection '? E puoi mostrare la definizione della classe per 'Part'? –

+0

Provando questo ora. La parte è semplice POCO con {get; impostato; } oggetti di scena – parliament

+0

'Part' ha un costruttore senza parametri? –

risposta

9

questione centrale è che MVC e WebAPI utilizzano diversi modelli b inders. Anche le interfacce di base sono diverse.

Mvc - System.Web.Mvc.IModelBinder 
Web API - System.Web.Http.ModelBinding.IModelBinder 

Quando si inviano i dati con il vostro $ .ajax chiamata, si sta inviando seguente query parametri di stringa:

Parts[0][hasLabel]:label 
Parts[0][hasType]:type 
Parts[0][hasIndex]:1 
LastKey:Last Key 
Term:Term 

Mentre, formato corretto che avrebbe legato con MVC legante modello predefinito è diversa convenzione di denominazione per nomi dei parametri:

Parts[0].hasLabel:label 
Parts[0].hasType:type 
Parts[0].hasIndex:1 
LastKey:Last Key 
Term:Term 

Quindi, questa chiamata di metodo avrebbe funzionato:

$.ajax({ 
      url: "Controller/AutoCompleteHandler?Parts[0].hasLabel=label&Parts[0].hasType=type&Parts[0].hasIndex=1&LastKey=Last+Key&Term=Term", 
      dataType: "json", 
      success: function(jsonData) { ... } 
     }); 

È necessario costruire la stringa di query rispettando le convenzioni di denominazione del raccoglitore modello MVC.

Inoltre l'attributo [FromUri] nell'azione di esempio viene completamente ignorato, poiché non è noto a MVC DefaultModelBinder.

+0

Grazie per la risposta, ma sapevo già così tanto. 2 possibili soluzioni sarebbe quella di forzare la stringa url nella convenzione corretta sul lato client, la mia domanda qui: http://stackoverflow.com/questions/17580471/javascript-regex-to-coerce-url-string-returned-from -param-in-mvc-model-bindi, OPPURE crea un raccoglitore modello personalizzato per gestire la convenzione $ .param() predefinita, la mia domanda qui: http://stackoverflow.com/q/17558735/1267778 .. Ma io ' Sto pensando che la soluzione più pulita potrebbe essere quella di rendere MVC supporto FromUri, che è quello che questa domanda è per. Se nessuno può rispondere, segnerò la tua risposta – parliament

+0

Regex è una soluzione sufficientemente pulita, quindi contrassegnerò la tua come risposta perché è comunque valida.Ma se qualcuno può effettivamente rispondere alla vera domanda su come far funzionare FromUri in MVC, lo segnerò. Grazie o – parliament

+1

Penso che rendere il binding delle API Web funzioni nel controller MVC sarebbe uno sforzo enorme. Le pipeline sono completamente diverse e per invocare l'associazione dell'API Web occorrerebbe istanziare correttamente un gruppo di oggetti specifici di livello inferiore del web-API (HttpControllerDescriptor, HttpActionDescriptor, ModelBindingContext, ecc.). – Nenad

Problemi correlati