[英]Deserialize a complex json object c#
我有这样一个json对象:
{
"status": "Success",
"value": [
[
"2019-10-21T11:48:00Z",
"010719/360",
"hodler@hodler.hodler",
{
"role": "hodler",
"company": "Proximus",
"first_name": "Ivan",
"last_name": "Holms",
"modification_date": "2019-10-21 10:33:39"
}
]
]
}
在此之前,我总是使用var obj = JsonConvert.DeserializeObject<MyDistClass>(json);
但我不明白如何描述这个实体:
"value": [
[
"2019-10-21T11:48:00Z",
"010719/360",
"holder@holder.holder",
{
"role": "holder",
"company": "Proximus",
"first_name": "Marc",
"last_name": "Neukirch",
"modification_date": "2019-10-21T10:33:39"
}
]
]
我尝试了所有我知道的类,甚至尝试替换元组,但没有结果。 请帮帮我。
我可能会使用 Json.NET 将 JSON 解析为JObject
,然后从中提取相关值 - 尽可能使用JToken.ToObject<>
。
下面是一些看似有效的示例代码 - 但需要大量验证和一般整理。 更重要的是展示这个想法而不是其他任何事情:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string json = File.ReadAllText("test.json");
Result result = Result.FromJson(json);
Console.WriteLine(result.Status);
Console.WriteLine(result.Values.Count);
Console.WriteLine(result.Values[0].User.FirstName);
}
}
public sealed class Result
{
public string Status { get; }
public IReadOnlyList<ResultValue> Values { get; }
private Result(string status, IReadOnlyList<ResultValue> values) =>
(Status, Values) = (status, values);
public static Result FromJson(string json)
{
JObject parsed = JObject.Parse(json);
string status = (string) parsed["status"];
JArray array = (JArray) parsed["value"];
var values = array.Select(ResultValue.FromJToken).ToList().AsReadOnly();
return new Result(status, values);
}
}
public sealed class ResultValue
{
public DateTime Timestamp { get; }
public string Id { get; }
public string Email { get; }
public User User { get; }
private ResultValue(DateTime timestamp, string id, string email, User user) =>
(Timestamp, Id, Email, User) = (timestamp, id, email, user);
internal static ResultValue FromJToken(JToken token)
{
JArray array = (JArray) token;
DateTime timestamp = (DateTime) array[0];
string id = (string) array[1];
string email = (string) array[2];
User user = array[3].ToObject<User>();
return new ResultValue(timestamp, id, email, user);
}
}
// TODO: Make this immutable, or everything else immutable
public sealed class User
{
[JsonProperty("role")]
public string Role { get; set; }
[JsonProperty("company")]
public string Company { get; set; }
[JsonProperty("first_name")]
public string FirstName { get; set; }
[JsonProperty("last_name")]
public string LastName { get; set; }
[JsonProperty("modification_date")]
public DateTime ModificationDate { get; set; }
}
我能够生成一个转换器
似乎工作得很好。
这是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace QuickType
{
public partial class Request
{
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("value")]
public ValueElement[][] Value { get; set; }
}
public partial class ValueClass
{
[JsonProperty("role")]
public string Role { get; set; }
[JsonProperty("company")]
public string Company { get; set; }
[JsonProperty("first_name")]
public string FirstName { get; set; }
[JsonProperty("last_name")]
public string LastName { get; set; }
[JsonProperty("modification_date")]
public DateTimeOffset ModificationDate { get; set; }
}
public partial struct ValueElement
{
public string String;
public ValueClass ValueClass;
public static implicit operator ValueElement(string String) => new ValueElement { String = String };
public static implicit operator ValueElement(ValueClass ValueClass) => new ValueElement { ValueClass = ValueClass };
}
internal static class Converter2
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ValueElementConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ValueElementConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ValueElement) || t == typeof(ValueElement?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.String:
case JsonToken.Date:
var stringValue = serializer.Deserialize<string>(reader);
return new ValueElement { String = stringValue };
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<ValueClass>(reader);
return new ValueElement { ValueClass = objectValue };
}
throw new Exception("Cannot unmarshal type ValueElement");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (ValueElement)untypedValue;
if (value.String != null)
{
serializer.Serialize(writer, value.String);
return;
}
if (value.ValueClass != null)
{
serializer.Serialize(writer, value.ValueClass);
return;
}
throw new Exception("Cannot marshal type ValueElement");
}
public static readonly ValueElementConverter Singleton = new ValueElementConverter();
}
}
像这样反序列化:
var myObject = JsonConvert.DeserializeObject<Request>(json, Converter2.Settings);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.