2011-08-17 24 views
25

मुझे JSON Deserialization के साथ समस्या है जिसमें पॉलिमॉर्फिक ऑब्जेक्ट्स की एक सरणी शामिल है। मैंने here और here दस्तावेज क्रमबद्ध करने के लिए समाधानों का प्रयास किया है जो क्रमबद्ध करने के लिए बहुत अच्छा काम करते हैं, लेकिन दोनों deserialization पर उड़ते हैं।पॉलिमॉर्फिक ऑब्जेक्ट्स की एक सरणी के साथ JSON Deserialization

मेरे वर्ग संरचना इस प्रकार है:

IDable

[DataContract(IsReference=true)] 
public abstract class IDable<T> { 

    [DataMember] 
    public T ID { get; set; } 
} 

अवलोकन समूह

[DataContract(IsReference=true)] 
[KnownType(typeof(DescriptiveObservation))] 
[KnownType(typeof(NoteObservation))] 
[KnownType(typeof(NumericObservation))] 
[KnownType(typeof(ScoredObservation))] 
public class ObservationGroup : IDable<int> { 

    [DataMember] 
    public string Title { get; set; } 

    [DataMember] 
    public List<Observation> Observations { get; set; } 

    [OnDeserializing] 
    void OnDeserializing(StreamingContext context) 
    { 
     init(); 
    } 

    public ObservationGroup() { 
     init(); 
    } 

    private void init() 
    { 
     Observations = new List<Observation>(); 
     ObservationRecords = new List<ObservationRecord>(); 
    } 

} 

DescriptiveObservation

[DataContract(IsReference = true)] 
public class DescriptiveObservation : Observation 
{ 

    protected override ObservationType GetObservationType() 
    { 
     return ObservationType.Descriptive; 
    } 
} 

NoteObservation

[DataContract(IsReference = true)] 
public class NoteObservation : Observation 
{ 
    protected override ObservationType GetObservationType() 
    { 
     return ObservationType.Note; 
    } 
} 

NumericObservation

[DataContract(IsReference = true)] 
public class NumericObservation : Observation 
{ 
    [DataMember] 
    public double ConstraintMaximum { get; set; } 
    [DataMember] 
    public double ConstraintMinimum { get; set; } 
    [DataMember] 
    public int PrecisionMaximum { get; set; } 
    [DataMember] 
    public int PrecisionMinimum { get; set; } 
    [DataMember] 
    public string UnitType { get; set; } 

    protected override ObservationType GetObservationType() 
    { 
     return ObservationType.Numeric; 
    } 
} 

ScoredObservation

[DataContract(IsReference = true)] 
public class ScoredObservation : Observation { 
    [DataMember] 
    public int Value { get; set; } 

    protected override ObservationType GetObservationType() { 
     return ObservationType.Scored; 
    } 
} 

मैं का उपयोग करने के निष्पक्ष हूँ या तो JavaScriptSerializer या Newtonsoft JSON पुस्तकालय में बनाया गया।

क्रमबद्धता कोड

var settings = new Newtonsoft.Json.JsonSerializerSettings(); 
settings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects; 

Newtonsoft.Json.JsonConvert.SerializeObject(AnInitializedScoresheet, Newtonsoft.Json.Formatting.None, settings); 

Deserialization कोड

return Newtonsoft.Json.JsonConvert.DeserializeObject(returnedStringFromClient, typeof(Scoresheet)); 
//Scoresheet contains a list of observationgroups 

त्रुटि है कि मैं पाने के

"प्रकार ProjectXCommon.DataStores.Observation का एक उदाहरण नहीं बना सका है। प्रकार एक अंतरफलक है या अमूर्त वर्ग और तत्काल नहीं किया जा सकता है। "

किसी भी मदद की बहुत सराहना की जाएगी!

+0

मैं बहुत यकीन है कि यह अपने 'सूची से संबंधित है हूँ' 'deserializers का एक प्रकार का दृष्टांत की कोशिश कर रहे Observation' नहीं विशिष्ट प्रकार

इस तरह

यह वास्तव में है। न्यूटॉन्सॉफ्ट के साथ आप अपना स्वयं का कनवर्टर जोड़कर deserialization के हिस्सों को ओवरराइड कर सकते हैं (यहां एक उदाहरण है https://gist.github.com/1140171) मुझे यकीन नहीं है कि यह आपकी मदद करेगा हालांकि मैं पूरी तरह से निश्चित नहीं हूं लेकिन काफी हद तक यह मामला है। :) – Buildstarted

+0

जेसन नमूने सहायक होंगे – Frank

उत्तर

28

आपने deserialization पर कोई भी सेटिंग नहीं जोड़ा है। आपको TypeNameHandlingObject या All पर सेटिंग लागू करने की आवश्यकता है।

JsonConvert.DeserializeObject(
    returnedStringFromClient, 
    typeof(Scoresheet), 
    new JsonSerializerSettings 
    { 
     TypeNameHandling = TypeNameHandling.Objects 
    }); 

प्रलेखन:: TypeNameHandling setting

+0

दोह! उन लोगों के लिए जो अभी भी .NET जावास्क्रिप्टसेरियलाइज़र का उपयोग कर रहे हैं, आप 'नया जावास्क्रिप्टसेरियलाइज़र (नया सिस्टम.Web.Script.Serialization.SimpleTypeResolver()) का उपयोग भी कर सकते हैं। Deserialize (returnStringFromClient, typeof (Scoresheet)); ' – Chainlink

+1

RavenDB के निर्माण के रूप में 49 9 (RavenDB JSON का उपयोग करता है।नेट) एक जेनेरिक सूची का उपयोग करते समय जहां टी इंटरफ़ेस है, आपको [JsonProperty (TypeNameHandling = TypeNameHandling.All)] विशेषता जोड़ने की आवश्यकता है। यह अपवाद को हल करता है "प्रकार का उदाहरण नहीं बना सकता 'आपका इंटरफ़ेस' प्रकार एक इंटरफ़ेस या सारणी वर्ग है और इसे तत्काल नहीं किया जा सकता है।" – DalSoft

संबंधित मुद्दे