反序列化动态 JSON 类型



我想反序列化为不同参数返回不同数据的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,但无法正确执行此操作。

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

您可以构建一个自定义转换器,但处理此问题的一种简单方法是编写一个错误处理程序,以检测 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);

这会将posts设置为 Enumerable.Empty<ReaderPost> 。这仍然有点不令人满意,因为如果发生任何错误,将设置该属性。您可以构建一个完整的自定义转换器来执行此操作作为更完整的解决方案。

这是一个转换器可以解决这个问题:

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

通过使用 JSON。在 LINQ to JSON 中内置的 NET,您可以尝试如下操作:

JObject jObject = JObject.Parse(json);
GetReaderResponse response = new GetReaderResponse();
if (jObject["posts"] is JArray)
    response = jObject.ToObject<GetReaderResponse>();
// Do something with the response object.

其中json变量是需要反序列化的 JSON 字符串。

试试这个:

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

看完@Ilija的评论后,我想我可能已经找到了答案。我不想不使用字符串文字,所以我修改了我的类GetReaderResponse如下所示:

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

这听起来不错还是看起来很乱?

相关内容

  • 没有找到相关文章

最新更新