问题描述
我有一个非常不受欢迎的情况,需要我反序列化 JSON,其中值是 JSON.NET 的字段名称.假设我有以下结构非常正确的 JSON:
I have a very undesirable situation which requires me to deserialize the JSON where the values are field names with JSON.NET. Assuming that I have the following JSON which is very properly structured:
{
"name": "tugberk",
"roles": [
{ "id": "1", "name": "admin" },
{ "id": "2", "name": "guest" }
]
}
使用 JSON.NET 将其反序列化为 CLR 对象非常容易:
It's very easy to deserialize this with JSON.NET to a CLR object:
class Program
{
static void Main(string[] args)
{
var camelCaseSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var text = File.ReadAllText("user_normal.txt");
var obj = JsonConvert.DeserializeObject<User>(text, camelCaseSettings);
}
}
public class User
{
public string Name { get; set; }
public Role[] Roles { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
}
但是,在我目前的情况下,我有以下可怕的 JSON,它在值方面等同于上述 JSON:
However, in my current case, I have the following horrible JSON which is equivalent to above JSON in terms of values:
{
"name": "tugberk",
"roles": {
"1": { "name": "admin" },
"2": { "name": "guest" }
}
}
如您所见,roles
字段不是数组;它是一个对象,其中包含其他值作为对象,其唯一键作为字段名称(这太可怕了).使用 JSON.NET 将此 JSON 反序列化为上述 User
类的最佳方法是什么?
As you can see, roles
field is not an array; it's an object which contains other values as objects with it's unique keys as their field names (which is horrible). What's the best way to deserialize this JSON to above User
class with JSON.NET?
推荐答案
您可以创建一个自定义 JsonConverter
序列化/反序列化 Role[]
.然后,您可以使用 JsonConverterAttribute
装饰您的 Roles
属性,如下所示:
You can create a custom JsonConverter
which serializes/deserializes Role[]
. You can then decorate your Roles
property with the JsonConverterAttribute
like this:
public class User
{
public string Name { get; set; }
[JsonConverter(typeof(RolesConverter))]
public Role[] Roles { get; set; }
}
在您的转换器类中,您可以读取一个对象并返回一个数组.您的转换器类可能如下所示:
In your converter class you are able to read an object and return an array instead. Your converter class may look like this:
class RolesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Role[]);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// deserialize as object
var roles = serializer.Deserialize<JObject>(reader);
var result = new List<Role>();
// create an array out of the properties
foreach (JProperty property in roles.Properties())
{
var role = property.Value.ToObject<Role>();
role.Id = int.Parse(property.Name);
result.Add(role);
}
return result.ToArray();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
这篇关于使用 JSON.NET 反序列化其中值是字段名称的 JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!