2016-03-23 11 views
0

ich mit der Deserialisierung des Objekts am kämpfen ... Ich gleiche Objektmodell erstellt haben, sowohl in meiner Anwendung und Web-api ... es sieht aus wie untendeserialisieren Objekt von Web-api Antwort

public class Project 
{ 
    // some propeties of project object.. 
    public SpecificationCollection Specs { get; set; } 
    public Project() 
    { 
     Specs = new SpecificationCollection(); 
    } 
} 

[Serializable()] 
public class SpecificationCollection : CollectionBase 
{ 
    public ProjectSpec this[int index] 
    { 
     get { return (ProjectSpec)List[index]; } 
     set { List[index] = value; } 
    } 
    //other implemented methods 
} 

public class ProjectSpec 
{ 
    //Properties 
    //Some other class object is also in this class but as of now i am not  
    //getting ProjectSpec 
} 

I folgendes haben versucht:

{using newtonsoft refrence here} 
Dim settings As New JsonSerializerSettings() 
settings.TypeNameHandling = TypeNameHandling.All //asme in auto typenamehandling 
Dim str As Object = Await response.Content.ReadAsStringAsync() 
Dim deserializedList As Project = JsonConvert.DeserializeObject(Of Project)(str, settings) 

Und das auch:

Await response.Content.ReadAsAsync(Of Project)() 

ich erhalte das Objekt Projekt umgewandelt f aber nicht die Sammlung. Bitte beachten Sie, wie Sie diese Situation beurteilen können. Dank

SAMPLE JSON

{"ProjectID":134,"ProjectName":"ABC","LPID":"","DNumber":0,"OrgnCode":"SPt","OrgnDesc":null,"SRatingCode":"AANSub","SRatingDesc":"AASub","ProjectConCode":"","ProjectCon":"desc","OrTCode":"Csity","OrTDesc":"Corsity","Projectsdf":"Miscld","ProjectType":"Miscellaneous","ProjectStatus":"","Street1":"","Street2":"","Street3":"","City":"Princeton","State":"NJ","StateName":"NY","PostalCode":"081","CountyCode":null,"CountyName":null,"CountryCode":"USA   ","CountryName":"UNITED STATES","TCode":"AA03","TName":"A03","IsA":false,"IsF1":false,"IsF2":false,"IsBacked":false,"IsMeeting":false,"IsVerified":true,"HSpec":false,"NumSpecs":0,"BidDate":"1901-01-01T00:00:00","BidStartDate":"0001-01-01T00:00:00","BidEndDate":"0001-01-01T00:00:00","EnteredBy":"User","EnteredDate":"2014-02-26T14:39:00","LockedBy":null,"LockedDate":"0001-01-01T00:00:00","CreatedBy":"dfg","CreatedDate":"2014-02-26T14:39:00","ModifiedBy":"dfgl","ModifiedDate":"2014-05-07T15:03:00","DeletedDate":null,"SysDate":"2016-01-07T07:11:00","TotalRows":0,"MonthsBack":"0001-01-01T00:00:00","SkID":-2147483648,"ArchID":"dfgdfg","AuthoredBy":"0","DModifiedDate":"1901-01-01T00:00:00","DVersion":0,"Flag":0,"OClassCode":null,"ProjectOrClass":null,"StCode":"DEFAULT","StDesc":null,"Specs":[{"SpecId":51993,"ESpecID":"558","Origin":"OS","OrName":"Openings Studio","WriterID":null,"WriterName":null,"DistName":"","ArchitectName":null,"SpecDate":"0001-01-01T00:00:00","SpecEstBidDate":"0001-01-01T00:00:00","ContractorName":null,"ProductLines":null,"CreatedDate":"2014-03-10T11:34:00","CreatedBy":"dfgdfg","ModifiedDate":"2014-03-10T11:34:00","ModifiedBy":"dfgdfg","STProjectName":null,"OwnerType":null,"SRating":null,"StickRating":null,"ProjectValue":0.0},{"SpecId":52000,"ESpecID":"635","Origin":"dfgdfg","OrName":"dfgdfg","WriterID":null,"WriterName":null,"DistName":"","ArchitectName":null,"SpecDate":"0001-01-01T00:00:00","SpecEstBidDate":"0001-01-01T00:00:00","ContractorName":null,"ProductLines":null,"CreatedDate":"2014-03-10T14:08:00","CreatedBy":"SpecTrak","ModifiedDate":"2014-03-10T14:08:00","ModifiedBy":"dfgdfgdfg","STProjectName":null,"OwnerType":null,"SRating":null,"StickRating":null,"ProjectValue":0.0}]} 
+0

Web API-Objekte nicht deserialisieren. Können Sie diesen Link überprüfen, um zu überprüfen, ob Ihr Project-Objekt mit dem erwarteten JSON kompatibel ist? http://jsonutils.com/ –

+1

Ihren JSON-String Put –

+0

bearbeitet Update sehen ..... Ich habe das gleiche in obigem Link von Som ... seine Schaffung IList .... Ich habe versucht, dass mein app in und Arbeits gut ... kann ich es in Sammlungsobjekt bekommen? wie es an vielen Orten bereits umgesetzt ist, ändert sich das –

Antwort

2

Das Problem ist, dass CollectionBase ist ein nicht-generisch, nicht typisierte Sammlung und hat somit Json.NET keine Möglichkeit zu wissen, wie ihre Produkte deserialisieren es sei denn, die $type Metadaten-Eigenschaften vorhanden sind im eingehenden JSON - was sie anscheinend nicht sind. In der Tat ist diese Klasse considered to be obsolete. Microsofts Richtlinie When to Use Generic Collections Zustand:

generische Sammlungen Verwendung wird allgemein empfohlen, weil Sie den unmittelbaren Nutzen des Typs Sicherheit gewinnen, ohne von einer Basiskollektionstyp abzuleiten und mit typspezifischen Elemente implementieren. Generische Auflistungstypen erzielen im Allgemeinen auch bessere Ergebnisse als die entsprechenden nichtgenerischen Auflistungstypen (und besser als Typen, die von nicht generischen Basisauflistungstypen abgeleitet werden), wenn die Auflistungselemente Werttypen sind, da bei Generika die Elemente nicht gepackt werden müssen.

So wird stattdessen empfohlen von System.Collections.ObjectModel.Collection<T> zu erben:

public class SpecificationCollection : Collection<ProjectSpec> 
{ 
} 

aber sagen, dass, wenn Sie müssen weiterhin CollectionBase verwenden, können Sie Ihre SpecificationCollectionICollection<ProjectSpec> implementieren machen könnte obwohl sie unter untypisierten . Wenn Sie das tun, wird Json.NET der Lage sein, es zu deserialisieren erfolgreich:

[Serializable()] 
public class SpecificationCollection : TypedCollectionBase<ProjectSpec> 
{ 
} 

[Serializable()] 
public class TypedCollectionBase<TItem> : CollectionBase, IList<TItem> 
{ 
    #region IList<TItem> Members 

    public int IndexOf(TItem item) 
    { 
     return List.IndexOf(item); 
    } 

    public void Insert(int index, TItem item) 
    { 
     List.Insert(index, item); 
    } 

    public TItem this[int index] 
    { 
     get { return (TItem)List[index]; } 
     set { List[index] = value; } 
    } 

    #endregion 

    #region ICollection<TItem> Members 

    public void Add(TItem spec) 
    { 
     List.Add(spec); 
    } 

    public bool Contains(TItem item) 
    { 
     return List.Contains(item); 
    } 

    public void CopyTo(TItem[] array, int arrayIndex) 
    { 
     foreach (var item in this) 
      array[arrayIndex++] = item; 
    } 

    public bool IsReadOnly { get { return List.IsReadOnly; } } 

    public bool Remove(TItem item) 
    { 
     int index = IndexOf(item); 
     if (index >= 0) 
      RemoveAt(index); 
     return index >= 0; 
    } 

    #endregion 

    #region IEnumerable<TItem> Members 

    public new IEnumerator<TItem> GetEnumerator() 
    { 
     return List.Cast<TItem>().GetEnumerator(); 
    } 

    #endregion 
} 

Und wenn Sie nicht das Design Ihrer SpecificationCollection in irgendeiner Weise ändern können, müssen Sie Ihre eigenen JsonConverter schreiben, es deserialisieren:

public class CollectionBaseConverter<TCollection, TItem> : JsonConverter where TCollection : CollectionBase 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(TCollection).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     TCollection collection = (TCollection)(existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator()); 
     var wrapper = new CollectionBaseWrapper<TCollection, TItem>(collection); 
     serializer.Populate(reader, wrapper); 
     return collection; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var collection = (TCollection)value; 
     serializer.Serialize(writer, collection.Cast<TItem>()); 
    } 
} 

class CollectionBaseWrapper<TCollection, TItem> : ICollection<TItem> where TCollection : CollectionBase 
{ 
    readonly IList collection; 

    public CollectionBaseWrapper(TCollection collection) 
    { 
     if (collection == null) 
      throw new ArgumentNullException(); 
     this.collection = collection; 
    } 

    public void Add(TItem item) 
    { 
     collection.Add(item); 
    } 

    public void Clear() 
    { 
     collection.Clear(); 
    } 

    public bool Contains(TItem item) 
    { 
     return collection.Contains(item); 
    } 

    public void CopyTo(TItem[] array, int arrayIndex) 
    { 
     foreach (var item in this) 
      array[arrayIndex++] = item; 
    } 

    public int Count { get { return collection.Count; } } 

    public bool IsReadOnly { get { return collection.IsReadOnly; } } 

    public bool Remove(TItem item) 
    { 
     bool found = collection.Contains(item); 
     if (found) 
      collection.Remove(item); 
     return found; 
    } 

    public IEnumerator<TItem> GetEnumerator() 
    { 
     return collection.Cast<TItem>().GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

Dann ist es in den Einstellungen wie folgt verwenden:

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, Converters = new[] { new CollectionBaseConverter<SpecificationCollection, ProjectSpec>() } }; 
var deserializedList = JsonConvert.DeserializeObject<Project>(str, settings); 
Verwandte Themen