2014-12-24 3 views
1

다른 매개 변수에 대해 다른 데이터를 반환하는 json을 deserialize하고 싶습니다. 는 대부분 내가 얻을 : Deserialise 동적 json 유형

{"posts": [{ "id" : 1, "name":"post1" },{ "id" : 1, "name":"post1" }]} 

그러나

때로는 반환 된 데이터가

{"posts": false} 

입니다 내가

public class GetReaderResponse 
{ 
    public IEnumerable<ReaderPost> posts {get; set;} 
} 

public class ReaderPost 
{ 
    public int id {get; set;} 
    public string name{get; set;} 
} 

사용하고있는 다음과 같은 클래스로이 직렬화하는 C#을 json.net하지만, 이 작업을 올바르게 수행 할 수 없습니다. ,이 같은가 someting를 시도 할 수 있습니다 JSON에 LINQ에 내장 JSON.NETs를 사용하여

public class GetReaderResponse 
{ 
    public bool posts { get; set; } 
    public ReaderPost[] post { get; set; } 
} 

답변

2

는 사용자 지정 변환기를 만들 수 있지만,이 문제를 해결할 수있는 가장 쉬운 방법은 posts 속성 오류를 감지 오류 핸들러를 작성하는 것입니다 : 이것은 Enumerable.Empty<ReaderPost>posts을 설정

var settings = new JsonSerializerSettings(); 

settings.Error += (sender, args) => 
{ 
    if (string.Equals("posts", args.ErrorContext.Path, StringComparison.OrdinalIgnoreCase)) 
    { 
     var currentObject = args.CurrentObject as GetReaderResponse; 

     currentObject.posts = Enumerable.Empty<ReaderPost>(); 

     args.ErrorContext.Handled = true; 
    } 
}; 

GetReaderResponse resp = 
    JsonConvert.DeserializeObject<GetReaderResponse>(json, settings); 

. 오류가 발생하면 속성이 설정되므로 여전히 만족스럽지 않습니다. 보다 완벽한 솔루션으로이를 수행 할 수있는 완전한 사용자 지정 변환기를 구축 할 수 있습니다.

다음은이 처리됩니다 컨버터입니다 :

public class PostsConverter : JsonConverter 
{ 
    public override object ReadJson(
     JsonReader reader, 
     Type objectType, 
     object existingValue, 
     JsonSerializer serializer) 
    { 
     JToken val = JValue.ReadFrom(reader); 
     object result = null; 

     if (val.Type == JTokenType.Array) 
     { 
      result = val.ToObject<IEnumerable<ReaderPost>>(); 
     } 
     else if (val.Type == JTokenType.Boolean) 
     { 

      result = Enumerable.Empty<ReaderPost>(); 
     } 

     return result; 
    } 

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

    public override bool CanConvert (Type type) 
    { 
     return typeof(IEnumerable<ReaderPost>).IsAssignableFrom(type); 
    } 

    public override bool CanRead 
    { 
     get { return true; } 
    } 
} 

사용법 :

var settings = new JsonSerializerSettings(); 

settings.Converters = new [] { new PostsConverter() }; 

GetReaderResponse resp = 
    JsonConvert.DeserializeObject<GetReaderResponse>(json, settings); 

예 :https://dotnetfiddle.net/i9CXwp

+0

감사합니다. 이것은 잘 작동하는 것 같다. – Shubhan

0

이 시도 비 직렬화 할 필요가있다.

+0

미안하지만 난 JSON에서 오타를 수정했습니다. 나는 '포스트'를 두 번 얻는다. 당신의 대답은 도움이되지 않습니다. – Shubhan

1

: json 변수는 JSON 문자열이

JObject jObject = JObject.Parse(json); 
GetReaderResponse response = new GetReaderResponse(); 
if (jObject["posts"] is JArray) 
    response = jObject.ToObject<GetReaderResponse>(); 

// Do something with the response object. 

입니다

Newtonsoft.Json.JsonConvert.DeserializeObject<GetReaderResponse>(dataString); 
0

@ Ilija의 의견을 읽은 후에 대답을 찾은 것 같습니다.

public class GetReaderResponse 
{ 
    public dynamic posts {get; set;} 
    public IEnumerable<ReaderPost> Posts 
    { 
     get 
     { 
      if (posts is bool) 
       return new ReaderPost[0]; 

      return posts.ToObject<IEnumerable<ReaderPost>>();    
     } 
    } 
} 

이 소리 잘합니까하거나 지저분한 보입니까 : 나는 내 수업 GetReaderResponse 아래처럼 보이도록 수정 그래서 나는 문자열 리터럴을 사용하지 싶지 않았다?