我想反序列化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);
答案 0 :(得分:2)
您可以构建自定义转换器,但处理此问题的一种简单方法是编写一个错误处理程序,以检测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);
答案 1 :(得分:1)
通过使用LINQ to JSON内置的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字符串。
答案 2 :(得分:0)
试试这个:
public class GetReaderResponse
{
public bool posts { get; set; }
public ReaderPost[] post { get; set; }
}
答案 3 :(得分:0)
在阅读@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>>();
}
}
}
这听起来不错还是看起来很麻烦?