2011-08-17 28 views
25

Bir polimorfik nesneler dizisini içeren JSON Deserialization ile ilgili bir sorun yaşıyorum. Serileştirme için mükemmel çalışan, here ve here belgelendirilmiş serileştirme için çözümler denedim, ancak her ikisi de seri hale getirme üzerinde patlar. aşağıdaki gibiJSON Polimorfik nesneler dizisi ile serileştirme

Benim sınıf yapısı şöyledir:

IDable

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

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

Gözlem Grubu

[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; 
    } 
} 

ben kullanmaya tarafsız değilim ya JavaScriptSerializer veya Newtonsoft JSON kütüphanesinde inşa etti.

Serile Kod

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

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

Seri kaldırma Kod

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

Ben

"tipi ProjectXCommon.DataStores.Observation örneğini oluşturulamadı olduğunu olsun hatası. Tür bir arayüz veya soyut sınıf ve instantated olamaz. "

Herhangi bir yardım çok takdir edilecektir!

+0

' deserializers 'bir tür örneğini çalışıyoruz Observation' değil belirli tip Bunun gibi

aslında öyle. Newtonsoft ile kendi Dönüştürücünüzü ekleyerek serileştirmenin parçalarını geçersiz kılabilirsiniz (burada bir örnek https://gist.github.com/1140171) Eminim ki bu tamamen size yardımcı olamayacağından emin olabilirsiniz. ama oldukça kesin bu durumda. :) – Buildstarted

+0

json örnekleri yararlı olurdu – Frank

cevap

28

Serileştirme sonrasında herhangi bir ayar eklemediniz. Ayarları TypeNameHandlingObject veya All olarak ayarlamalısınız.

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

: Ben senin `List alakalı eminim TypeNameHandling setting

+0

Doh! .NET JavascriptSerializer'ı kullananlar için 'yeni JavaScriptSerializer'ı (yeni System.Web.Script.Serialization.SimpleTypeResolver()) kullanabilirsiniz. Deserialize (returnStringFromClient, typeof (Scoresheet)); – Chainlink

+1

RavenDB build 499 (RavenDB) JSON kullanır.NET) T'nin bir arabirim olduğu genel bir liste kullanırken, [JsonProperty (TypeNameHandling = TypeNameHandling.All)] özniteliğini eklemeniz gerekir. Bu durum, "Arayüzünüzün bir tür örneğini oluşturamadı" Türü, bir arabirim veya soyut sınıftır ve sisteme girilemez. " – DalSoft