2012-10-12 14 views
6

ho un obbligo per gli utenti di modificare un elenco di citazioni per un cavo, le citazioni possono essere diversi tipi come ad esempio:pubblicazione di un insieme di sottoclassi

  • QuoteForProductTypeA
  • QuoteForProductTypeB

Tutti i tipi di quote condividono una classe base comune, come QuoteBase.

Ho le mie quotazioni che si visualizzano bene sul front-end e sembrano postback anche i dati corretti.

Tuttavia, sul server, ovviamente, non sa quale sottoclasse utilizzare, quindi utilizza solo la classe base.

Penso di aver bisogno di una sorta di raccoglitore modello personalizzato per WebApi per verificare un campo nascosto come ModelType che contiene il tipo di oggetto nella raccolta, il raccoglitore modello crea quindi un nuovo oggetto di questo tipo e lega il proprietà dai miei valori pubblicati a questo oggetto.

Tuttavia, sono bloccato a questo punto con pochissima documentazione/blog su come farlo.

Ho controllato il codice sorgente per WebApi per vedere se riesco ad estendere un modello predefinito, ma qualsiasi valore predefinito è classi sigillate.

Posso solo implementare IModelBinder con l'aspetto di esso, posso creare il tipo di modello corretto cercando un valore chiamato ModelType, ma poi non sono sicuro di come riempire il resto dei valori nelle mie sottoclassi, se c'era un modello di default che stavo ereditando da mi piacerebbe solo chiamare il metodo di associazione delle classi di base.

risposta

9

Se la raccolta dei post proviene dal corpo della richiesta, non passerà attraverso il raccoglitore del modello. Le API Web utilizzeranno il formattatore per deserializzare il contenuto.

Se si vuole semplicemente supportare json, è abbastanza facile. Basta aggiungere seguente codice al vostro web api config:

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto; 

L'impostazione permetterà json.net per salvare nome di tipo nel payload se il tipo di esecuzione è diverso con il tipo di dichiarazione. Quando lo si registra, json.net deserializza il payload al tipo specificato nel payload.

un carico utile del campione si presenta come:

{"$type":"MvcApplication2.Models.Car, MvcApplication2","SeatCount":10,"WheelCount":4,"Model":0,"Brand":null}] 
+0

Grazie, che fatto il trucco. Stavo serializzando il mio modello per JSON per knockoutJs per consumare con questo codice: Html.Raw (Json.Encode (Model)), tuttavia ho dovuto sostituire questo codice per usare invece il serializzatore Json.Net e specificare l'opzione TypeNameHandling lì anche ... nel caso gli altri stessero cercando la risposta. –

+1

Nel caso in cui sia utile a chiunque altro - '$ type' deve essere il primo campo elencato nell'oggetto o JSON.Net non sarà in grado di deserializzarlo. –