2011-10-19 24 views
20

Tôi đang tiêu thụ một số dịch vụ web ARCGis và chúng có một số thiết kế JSON không may. Ví dụ, họ có thể cung cấp cho một cái gì đó như thế này:JSON.NET - Loại điều kiện Deserialization

{ 
geometryType: "esriGeometryPolygon" 
geometry: { 
-rings: [ 
-[.blah..... }} 

Bây giờ, tùy thuộc vào GeometryType giá trị thông qua tại, các hình học đối tượng có thể là một trong các loại đối tượng khác nhau. trong trường hợp trên, nút hình học thuộc loại Đa giác.

vì vậy, câu hỏi là; trong JSON.NET có cách nào để ghi nhận kiểu gõ có điều kiện này không? nếu không (mà tôi nghi ngờ có), có cách nào để xây dựng một nhà cung cấp cho deserializing rằng hình học nút, dựa trên các thông tin đối tượng ở trên? nếu không, có cách nào được khuyến nghị để giải quyết vấn đề này không?

chỉnh sửa: i nhìn khá rộng rãi vào việc xây dựng một bộ chuyển đổi tùy chỉnh, nhưng vấn đề với bộ chuyển đổi là họ có phương pháp trừu tượng này:

public override T Create (Type objectType) 
tuy nhiên

, tôi không có cách nào để biết những gì loại để tạo ra ở đây , tôi cần biết loại đối tượng nào được chỉ định trong JSON ở trên.

cảm ơn!

Trả lời

9

Tôi đặt cùng một công cụ chuyển đổi mẫu để chỉ cho bạn đúng hướng. Dưới đây là mẫu chuỗi JSON của tôi:

{GeometryType: "esriGeometryPolygon", hình học: {nhẫn: 5}}

{GeometryType: "esriGeometryOther", hình học: {nhẫn: 5}}

tôi đã thử nghiệm nó như thế này:

var serializer = new JsonSerializer(); 
var geometry = serializer.Deserialize<Geometry>(new JsonTextReader(new StringReader(jsonData))); 

//Should have correctly typed instance here... 

và đây là công cụ chuyển đổi và hình học mẫu đối tượng:

public class GeometryConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 

     reader.Read(); // startobject 

     //we should be at geometry type property now 
     if ((string)reader.Value != "geometryType") throw new InvalidOperationException(); 

     reader.Read(); //propertyName 

     var type = (string)reader.Value; 

     Geometry value; 

     switch(type) 
     { 
      case "esriGeometryPolygon": 
       value = new PolygonGeometry(); 
       break; 
      case "esriGeometryOther": 
       value = new OtherGeometry(); 
       break; 
      default: 
       throw new NotSupportedException(); 
     } 

     reader.Read(); // move to inner object property 
     //should probably confirm name here 

     reader.Read(); //move to inner object 

     serializer.Populate(reader, value); 

     reader.Read(); //move outside container (should be end object) 

     return value; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(Geometry).IsAssignableFrom(objectType); 
    } 
} 

[JsonConverter(typeof(GeometryConverter))] 
public class OtherGeometry : Geometry 
{ 

} 

[JsonConverter(typeof(GeometryConverter))] 
public class PolygonGeometry : Geometry 
{ 

} 

[JsonConverter(typeof(GeometryConverter))] 
public class Geometry 
{ 
    public int rings { get; set; } 
} 
0

Tôi đã có một vấn đề tương tự và giải quyết nó với một JsonSchema, nhờ Yuval Itzchakov 's giúp đỡ: Deserialize json in a “TryParse” way

Dường như một cái gì đó như thế:

// Check json schema : 
    const string errorJsonSchema = 
     @"{ 
       'type': 'object', 
       'properties': { 
        'error': {'type':'object'}, 
        'status': {'type': 'string'}, 
        'code': {'type': 'string'} 
       }, 
       'additionalProperties': false 
      }"; 
    JsonSchema schema = JsonSchema.Parse(errorJsonSchema); 
    JObject jsonObject = JObject.Parse(jsonResponse); 
    if (!jsonObject.IsValid(schema)) 
    { 
     error = null; 
     return false; 
    } 

    // Try to deserialize : 
    try 
    { 
     error = new JsonSerializer<Error>.DeserializeFromString(jsonResponse); 
     return true; 
    } 
    catch 
    { 
     // The JSON response seemed to be an error, but failed to deserialize. 
     // This case should not occur... 
     error = null; 
     return false; 
    } 
Các vấn đề liên quan