2016-06-21 8 views
1

私はいくつかのJSONを2種類用意しています。場合によってはlocationの値は文字列であり、時にはそれがオブジェクトです。これは、最初の形式のサンプルである:JSON値は時には文字列であり、時にはオブジェクトです

{ 
    "result": [ 
    { 
     "upon_approval": "Proceed to Next Task", 
     "location": "", 
     "expected_start": "" 
    } 
    ] 
} 
このため

クラス定義:ここ

public class Result 
{ 
    public string upon_approval { get; set; } 
    public string location { get; set; } 
    public string expected_start { get; set; } 
} 

public class RootObject 
{ 
    public List<Result> result { get; set; } 
} 

は、JSONは、第二のフォーマットである。このため

{ 
    "result": [ 
    { 
     "upon_approval": "Proceed to Next Task", 
     "location": { 
     "display_value": "Corp-HQR", 
     "link": "https://satellite.service-now.com/api/now/table/cmn_location/4a2cf91b13f2de00322dd4a76144b090" 
     }, 
     "expected_start": "" 
    } 
    ] 
} 

クラス定義:

public class Location 
{ 
    public string display_value { get; set; } 
    public string link { get; set; } 
} 

public class Result 
{ 
    public string upon_approval { get; set; } 
    public Location location { get; set; } 
    public string expected_start { get; set; } 
} 

public class RootObject 
{ 
    public List<Result> result { get; set; } 
} 

dese JSON形式がクラスと一致しないときにエラーが発生しますが、JSON形式が変更されるため、使用するクラスを事前に知る必要はありません。では、これらの2つのJSON形式を動的に1つのクラスセットに逆シリアル化する方法を教えてください。

JavaScriptSerializer ser = new JavaScriptSerializer(); 
ser.MaxJsonLength = 2147483647; 
RootObject ro = ser.Deserialize<RootObject>(responseValue); 
+0

あなたの "result"配列には両方が含まれていますか? – Eser

+0

@Eserいいえ、いずれかのクラス定義のみを含めることはできますが、jsonレスポンスは文字列またはクラスのいずれかを持っています。だから私はそれらの文字列の値を無視する方法を知りません。 –

+1

[This(http://stackoverflow.com/questions/22052430/how-to-handle-json-that-returns-both-a-string-and-a-string-array)はヒントを与えることができます.. .. – Eser

答えて

2

をカスタムJavaScriptConverterクラスを作成し、シリアライザに登録する必要があります。この問題を解決するために:

これは私が今、デシリアライズしています方法です。シリアライザはresultデータをDictionary<string, object>にロードし、コンバータに渡します。コンバータでは、内容を検査して使用可能なオブジェクトに変換できます。要するに、これにより、両方のJSON形式で2番目のクラスセットを使用できます。ここで

は、コンバータのコードです:

class ResultConverter : JavaScriptConverter 
{ 
    public override IEnumerable<Type> SupportedTypes 
    { 
     get { return new List<Type> { typeof(Result) }; } 
    } 

    public override object Deserialize(IDictionary<string, object> dict, Type type, JavaScriptSerializer serializer) 
    { 
     Result result = new Result(); 
     result.upon_approval = GetValue<string>(dict, "upon_approval"); 
     var locDict = GetValue<IDictionary<string, object>>(dict, "location"); 
     if (locDict != null) 
     { 
      Location loc = new Location(); 
      loc.display_value = GetValue<string>(locDict, "display_value"); 
      loc.link = GetValue<string>(locDict, "link"); 
      result.location = loc; 
     } 
     result.expected_start = GetValue<string>(dict, "expected_start"); 
     return result; 
    } 

    private T GetValue<T>(IDictionary<string, object> dict, string key) 
    { 
     object value = null; 
     dict.TryGetValue(key, out value); 
     return value != null && typeof(T).IsAssignableFrom(value.GetType()) ? (T)value : default(T); 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

次に、このようにそれを使用します。ここでは

var ser = new JavaScriptSerializer(); 
ser.MaxJsonLength = 2147483647; 
ser.RegisterConverters(new List<JavaScriptConverter> { new ResultConverter() }); 
RootObject ro = serializer.Deserialize<RootObject>(responseValue); 

が短いデモです:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @" 
     { 
      ""result"": [ 
      { 
       ""upon_approval"": ""Proceed to Next Task"", 
       ""location"": { 
       ""display_value"": ""Corp-HQR"", 
       ""link"": ""https://satellite.service-now.com/api/now/table/cmn_location/4a2cf91b13f2de00322dd4a76144b090"" 
       }, 
       ""expected_start"": """" 
      } 
      ] 
     }"; 

     DeserializeAndDump(json); 
     Console.WriteLine(new string('-', 40)); 

     json = @" 
     { 
      ""result"": [ 
      { 
       ""upon_approval"": ""Proceed to Next Task"", 
       ""location"": """", 
       ""expected_start"": """" 
      } 
      ] 
     }"; 

     DeserializeAndDump(json); 

    } 

    private static void DeserializeAndDump(string json) 
    { 
     var serializer = new JavaScriptSerializer(); 
     serializer.RegisterConverters(new List<JavaScriptConverter> { new ResultConverter() }); 
     RootObject obj = serializer.Deserialize<RootObject>(json); 

     foreach (var result in obj.result) 
     { 
      Console.WriteLine("upon_approval: " + result.upon_approval); 
      if (result.location != null) 
      { 
       Console.WriteLine("location display_value: " + result.location.display_value); 
       Console.WriteLine("location link: " + result.location.link); 
      } 
      else 
       Console.WriteLine("(no location)"); 
     } 
    } 
} 

public class RootObject 
{ 
    public List<Result> result { get; set; } 
} 

public class Result 
{ 
    public string upon_approval { get; set; } 
    public Location location { get; set; } 
    public string expected_start { get; set; } 
} 

public class Location 
{ 
    public string display_value { get; set; } 
    public string link { get; set; } 
} 

は出力:

upon_approval: Proceed to Next Task 
location display_value: Corp-HQR 
location link: https://satellite.service-now.com/api/now/table/cmn_location/4a2cf91b13f2de00322dd4a76144b090 
---------------------------------------- 
upon_approval: Proceed to Next Task 
(no location) 
+0

ありがとうブライアン、それは非常に有用だった。あなたは私の仕事をとても簡単にしました。私は今あなたに借りています。 –

+0

心配はいりません。私は助けてくれてうれしいです。 –

関連する問題