[英]How to deserialize a list of values to C# objects
My application receives a JSON object as:我的应用程序收到一个 JSON 对象:
{
"names": [
"name_1",
"name_2"
]
}
I want to deserialize it to a list of Person
object, defined as:我想将其反序列化为
Person
对象列表,定义为:
class Person
{
public string Name { set; get; }
}
Currently, I am deserializing the JSON object to a list of strings then create a list of Person
manually like the following:目前,我正在将 JSON 对象反序列化为一个字符串列表,然后手动创建一个
Person
列表,如下所示:
var names = JsonConvert.DeserializeObject<List<string>>(json);
var people = new List<Person>();
foreach(var name in names)
people.Add(new Person(){ Name = name });
Instead, I am interested in something like the following:相反,我对以下内容感兴趣:
var people = JsonConvert.DeserializeObject<List<Person>>(json);
I am implementing the Person
deserializer as:我正在将
Person
反序列化器实现为:
public class PersonJsonConverter : JsonConverter
{
private readonly Dictionary<string, string> _propertyMappings;
public PersonJsonConverter()
{
_propertyMappings = new Dictionary<string, string>
{
{"name", nameof(Person.Name)}
};
}
public override bool CanConvert(Type objectType)
{
return objectType.GetTypeInfo().IsClass;
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
object instance = Activator.CreateInstance(objectType);
var props = objectType.GetTypeInfo().DeclaredProperties.ToList();
JObject obj = JObject.Load(reader);
foreach (JProperty jsonProperty in obj.Properties())
{
if (!_propertyMappings.TryGetValue(jsonProperty.Name, out var name))
name = jsonProperty.Name;
PropertyInfo prop = props.FirstOrDefault(
pi => pi.CanWrite && pi.Name == name);
prop?.SetValue(
instance,
jsonProperty.Value.ToObject(prop.PropertyType, serializer));
}
return instance;
}
}
This deserializer can deserilize object such as:这个反序列化器可以反序列化对象,例如:
{
"names": [
"name": "name_1",
"name": "name_2"
]
}
but not但不是
{
"names": [
"name_1",
"name_2"
]
}
Note that my application can receive both types of JSON objects, so better to have a common deserializer for both types.请注意,我的应用程序可以接收两种类型的 JSON 对象,因此最好为这两种类型拥有一个通用的反序列化器。
You have to deserialize names
to something like a JArray
, then foreach
each entry with a new Person('name')
.您必须将
names
反序列化为JArray
类的JArray
,然后使用new Person('name')
每个条目进行foreach
。 The JSON as you received it just doesn't match your desired schema.您收到的 JSON 与您想要的架构不匹配。 You have to manually transform it.
您必须手动转换它。
Please try below:请尝试以下:
class Person
{
public string Name { set; get; }
}
public class PersonJsonConverter : JsonConverter
{
// private readonly Dictionary<string, string> _propertyMappings;
public PersonJsonConverter()
{
/*_propertyMappings = new Dictionary<string, string>
{
{"name", nameof(Person.Name)}
};*/
}
public override bool CanConvert(System.Type objectType)
{
return objectType.GetTypeInfo().IsClass;
}
public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
{
object instance = Activator.CreateInstance(objectType);
// List<T> implements the non-generic IList interface
IList list = (IList)instance;
var typeInfo = objectType.GetTypeInfo();
var props = typeInfo.DeclaredProperties.ToList();
PropertyInfo prop = props.FirstOrDefault(pi => pi.PropertyType == typeof(Person));
JObject obj = JObject.Load(reader);
var namesArray = obj["names"]; // you can use this instead of for loop on obj.Properties.
/*foreach (JProperty jsonProperty in obj.Properties())
{
if (jsonProperty.Name == "names")
{
var namesArray = JArray.Parse(jsonProperty.Value.ToString());
*/
if (namesArray.Type == JTokenType.Array && prop != null)
{
foreach (var ja in namesArray)
{
object personInstance = Activator.CreateInstance(prop.PropertyType);
PropertyInfo personNamePropInfo = prop.PropertyType.GetProperty(nameof(Person.Name));
personNamePropInfo.SetValue(personInstance,
Convert.ChangeType(ja, personNamePropInfo.PropertyType), null);
list.Add(personInstance); // Whatever you need to add
}
}
/* break;
}
}*/
return instance;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
and use it like below:并像下面一样使用它:
var samplejson = @"{
""names"": [
""name_1"",
""name_2""
]
}";
var obj = JsonConvert.DeserializeObject<List<Person>>(samplejson, new JsonConverter[] { new PersonJsonConverter() });
The other json does not seem to be valid json.另一个 json 似乎不是有效的 json。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.