2011-08-17 48 views
25

Tôi đang gặp vấn đề với JSON Deserialization liên quan đến một mảng các đối tượng đa hình. Tôi đã thử các giải pháp cho serialization tài liệu herehere mà làm việc tuyệt vời cho serialization, nhưng cả hai thổi lên trên deserialization.JSON Deserialization với một mảng các đối tượng đa hình

cấu trúc lớp của tôi là như sau:

IDable

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

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

Observation Nhóm

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

Tôi không thiên vị để sử dụng một trong hai được xây dựng trong JavaScriptSerializer hoặc thư viện Newtonsoft JSON.

serialization Mã

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

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

Deserialization Mã

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

Loại Các lỗi mà tôi nhận được là

"Không thể tạo một thể hiện của loại ProjectXCommon.DataStores.Observation. Là một giao diện hoặc lớp trừu tượng và không thể diễn đạt được. "

Mọi trợ giúp sẽ được đánh giá cao!

+0

Tôi khá chắc chắn rằng nó liên quan đến 'của bạn Danh sách ' các deserializers đang cố gắng để nhanh chóng một loại của 'Observation' không phải là loại hình cụ thể nó thực sự là. Với Newtonsoft bạn có thể ghi đè lên các phần của deserialization bằng cách thêm Converter của riêng bạn (đây là một ví dụ https://gist.github.com/1140171) Tôi không chắc chắn bao nhiêu điều này sẽ giúp bạn mặc dù như tôi không hoàn toàn nhất định nhưng khá chắc chắn đây là trường hợp. :) – Buildstarted

+0

mẫu json sẽ hữu ích – Frank

Trả lời

28

Bạn chưa thêm bất kỳ cài đặt nào khi deserialization. Bạn cần áp dụng cài đặt với TypeNameHandling được đặt thành Object hoặc All.

Như thế này:

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

Tài liệu: TypeNameHandling setting

+0

Doh! Đối với những người vẫn sử dụng .NET JavascriptSerializer bạn cũng có thể sử dụng 'JavaScriptSerializer mới (new System.Web.Script.Serialization.SimpleTypeResolver()). Deserialize (returnStringFromClient, typeof (Scoresheet));' – Chainlink

+1

Khi xây dựng RavenDB 499 (RavenDB) sử dụng JSON.NET) khi sử dụng một danh sách chung mà T là một giao diện, bạn cần thêm thuộc tính [JsonProperty (TypeNameHandling = TypeNameHandling.All)]. Điều này sửa lỗi ngoại lệ "Không thể tạo một thể hiện của loại 'giao diện của bạn' Loại là một giao diện hoặc lớp trừu tượng và không thể được instantated." – DalSoft

Các vấn đề liên quan