2010-01-26 29 views
10

Desidero poter inviare JSON in contrapposizione a QueryStrings standard quando si effettua un post sui controller in ASP.Net MVC. Ho le cose front-end che funzionano bene (costruendo e poi inviando i miei oggetti JSON).ASP.Net MVC: invio JSON al controller

Il problema si verifica sul lato controller dove i ModelBinder predefiniti forniti con il framework MVC non supportano questo.

Ho visto una combinazione di modi per aggirare questo, uno di loro è quello di applicare un filtro che prende l'oggetto come parametro, utilizza una libreria JSON per de-serializzarlo e lo aggiunge ai parametri di azione. Questo non è l'ideale

L'altro modo migliore è utilizzare un Raccoglitore modello personalizzato. Tutti quelli che ho visto, tuttavia, presumeranno che avrà un solo modello e che sarà una classe piuttosto che una variabile. Se ne hai di più, si rompe.

Qualcun altro ha riscontrato questo? Un'idea che avevo era se potessi semplicemente scavalcare il modo in cui MVC si occupa di FormCollection e intercettare lì, aggiungendo i valori alla raccolta da solo e sperando che MVC possa fare il resto in modo normale. Qualcuno sa se è possibile?

Il problema chiave, penso, è che il mio problema non è con il binding perché i miei modelli di vista non sono diversi da come erano prima. Il problema è ottenere i valori da JSON Post.

Se sono corretto, MVC ottiene i valori da QueryString e lo inserisce nella raccolta moduli che viene quindi utilizzata per ModelBinding. Quindi il metodo corretto non dovrebbe essere quello di cambiare il modo in cui viene assegnato FormCollection?

Esempio di un'azione:

public ActionResult MyFirstAction(Int32 ID, PersonObject Person, ClassObject ClassDetails) 
{ 
//etc 
} 

I normali lavori di rilegatura, JSON e non tutti l'esempio del modello raccoglitori non funzionerà neanche. La mia soluzione migliore finora è quella di convertire l'oggetto in un dizionario e di eseguire il ciclo di ogni parametro e abbinarlo. Non sembra ideale.

+0

Se stai per votare, potresti spiegare perché? – Damien

+0

Scusate, sfortunatamente, quando sono andato a cliccare sulla stella preferita, ho cliccato accidentalmente per il voto negativo, anche dopo che l'ho già svalutato (è per questo che è andato dal 5 al 3). E ora ha detto subito dopo aver tentato di annullare ciò che ho accidentalmente fatto, che era troppo tardi per cambiare il mio voto, a meno che la domanda non venga modificata. Se apporti una modifica alla domanda, correggerò volentieri il mio voto. – jamesaharvey

+0

Nessun problema! Succede anche a me molte volte. – Damien

risposta

8

Io uso un modello personalizzato legante per JSON come questo:

public class JsonModelBinder<T> : IModelBinder { 
    private string key; 

    public JsonModelBinder(string requestKey) { 
     this.key = requestKey; 
    } 

    public object BindModel(ControllerContext controllerContext, ...) { 
     var json = controllerContext.HttpContext.Request[key]; 
     return new JsonSerializer().Deserialize<T>(json); 
    } 
} 

E poi legare in su in Global.asax.cs come questo:

ModelBinders.Binders.Add(
    typeof(Product), 
    new JsonModelBinder<Product>("ProductJson")); 

Si può leggere di più su questo qui : Inheritance is Evil: The Epic Fail of the DataAnnotationsModelBinder

EDIT

JsonModelBinder deve essere utilizzato sul parametro di azione del controller immesso solo come Prodotto. Int32 e ClassObject dovrebbero tornare a DefaultModelBinder. Stai riscontrando un risultato diverso?

+0

Quindi avresti bisogno di definire per quali tipi usarlo? – Damien

+0

Sì, è necessario specificare i tipi. Puoi descrivere la tua situazione in modo un po 'più dettagliato? Ho approfondito il binding dei modelli più recentemente e ci sono molte funzionalità non ovvie. –

+0

Bene con i tipi cosa devo fare per i parametri di azione che sono tipi primitivi/punti? Se invio ID Int32, Product Class crea un problema – Damien

Problemi correlati