Deserializzazione della proprietà automatica C # di JSON

Devo deserializzare alcuni oggetti JavaScript rappresentati in JSON in una class C # appropriata. Date le belle caratteristiche delle proprietà automatiche, preferirei averle in queste classi piuttosto che avere solo dei campi. Sfortunatamente, il motore di serializzazione .NET (almeno, per impostazione predefinita) ignora completamente le proprietà automatiche in fase di deserializzazione e si preoccupa solo del campo di supporto, che ovviamente non è presente nell’object JavaScript.

Dato che non esiste un modo standard per denominare i campi di backing e per essere onesti non voglio nemmeno preoccuparmi di “creiamo un object JavaScript che sembra avere dei campi di backing C #” visto che suona un po ‘sporco, l’unico modo Potrei serializzare i campi JavaScript per le proprietà automatiche di C # se potessi forzare il motore di serializzazione in qualche modo a ignorare il campo di supporto e usare direttamente la proprietà. Sfortunatamente, non riesco a capire come è fatto o se è ansible farlo. Qualsiasi idea sarebbe apprezzata.

EDIT : Ecco un esempio:

Javascript:

function Cat() { this.Name = "Whiskers"; this.Breed = "Tabby"; } var cat = new Cat(); 

Questo viene quindi serializzato su “{Name: ‘Whiskers’}”.

La class C #:

 [Serializable()] public class Cat { public string Name { get; set; } public string Breed { get; set; } } 

E il codice di deserializzazione, che fallisce:

 new DataContractJsonSerializer(typeof(Cat)).ReadObject(inputStream); 

Ed è evidente dall’eccezione che fallisce perché sta cercando il campo di supporto.

EDIT2 : Ecco l’eccezione, se questo aiuta (senza eccezioni interne):

System.Runtime.Serialization.SerializationException

“Il tipo di contratto di dati ‘Test.Cat’ non può essere deserializzato perché i membri dei dati richiesti ‘ k__BackingField, k__BackingField ‘ non sono stati trovati.”

Quello che sta succedendo qui è che il deserializzatore sta cercando di indovinare il nome dei tuoi campi di supporto. Puoi risolvere questo problema aggiungendo mappature esplicite (attributi DataContract / DataMember) come questo:

 [DataContract] public class Cat { [DataMember] public string Name { get; set; } [DataMember] public string Breed { get; set; } } 

Puoi farlo con JavaScriptSerializer trovato nello spazio dei nomi System.Web.Script.Serialization :

 JavaScriptSerializer serializer = new JavaScriptSerializer(); Cat c = serializer.Deserialize(jsonString); 

Ho oggetti POCO con proprietà automatiche e questo funziona bene.

EDIT: Ho scritto su JSON Serializers in .NET che confronta questo serializzatore con DataContractJsonSerializer .

la risposta di baretta ha risolto il k__BackingField per me. Solo una piccola aggiunta che puoi decorare questa class per serializzare automaticamente in XML o JSON in un modo simile:

 [Serializable, XmlRoot, DataContract] public class Cat { [XmlElement] [DataMember] public string Name { get; set; } [XmlElement] [DataMember] public string Breed { get; set; } } 

… e quindi utilizzare un DataContractJsonSerializer o XmlSerializer per prepararlo per l’endpoint.

Suppongo che tu stia passando dei dati tramite un servizio web. Se si utilizza la class WebService con l’attributo ScriptMethod non commentato, i metodi del servizio Web possono leggere JSON in modo nativo. Usano anche lo stesso JavaScriptSerializer menzionato sopra. Se stai usando WCF sono un po ‘più sfocato sulla logica.

Ma assicurati che il tuo object JSON restituisca dati per OGNI proprietà della tua class. Nel tuo errore, c’è menzione di una proprietà Breed che non è nel tuo esempio.

Inoltre, sul lato JavaScript, fare alla natura dynamic di JavaScript è facile aggiungere nuove proprietà ai tuoi oggetti. Questo a volte può portare a riferimenti circolari. Dovresti rimuovere tutti i dati aggiuntivi che potresti aver aggiunto (proprio come stai inviando i dati tramite il metodo web, quindi aggiungili di nuovo una volta che hai finito).