2016-06-21 7 views
1

두 가지 형식으로 제공되는 JSON이 있습니다. 경우에 따라 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": "" 
    } 
    ] 
} 

클래스 정의 :

이 제 1 포맷의 예이며
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; } 
} 

JSON 형식이 내 클래스와 일치하지 않을 때 오류가 발생하지만 JSON 형식이 변경되어 어떤 클래스를 사용할 지 미리 알 수 없습니다. 그렇다면 이러한 두 개의 JSON 형식을 동적으로 하나의 클래스 집합으로 역 직렬화 할 수 있습니까?

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 형식 모두에 대해 두 번째 클래스 집합을 사용할 수 있습니다. 이 같은

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(); 
    } 
} 
다음

사용 :

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

출력 :

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

짧은 데모입니다 여기에

는 컨버터에 대한 코드입니다
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

걱정할 필요가 없습니다. 다행히 도울 수있었습니다. –