[英]Deserialize an Anonymous Type From a Collection
我有以下格式的序列化JSON:
string json = @"[{"Name": "std_id","Value": "111"}, {"Name": "cust_id","Value": "444"}]"
如何将其反序列化为单个匿名对象,如下所示:
var paramObj = new {"std_id" = 111, "cust_id" = 444}
为什么要匿名对象? 您应该反序列化为如下类型
public class RootObject
{
public string Name { get; set; }
public string Value { get; set; }
}
然后,您实际拥有的是IEnumerable<RootObjct>
。 您可以使用use Linq并从中选择First()
RootObject = RootObjects.FirstOrDefault()
您可以将其反序列化为动态。 像这样:
var serializer = new JavaScriptSerializer();
var deserializedResult = serializer.Deserialize<dynamic>(json);
参考:
由于您说的是JSON对象中Name
和Value
属性的值可以变化,因此您将无法反序列化为匿名对象。 匿名类型是在编译时定义的,这意味着您需要提前知道属性名称才能定义它们。 解决该问题的唯一方法是代码生成,我认为在这种情况下这会显得过分杀伤力。 相反,我建议您反序列化为带有动态变量的JObject
。 这将使您非常接近所需的内容。 这是如何做:
string json = @"[
{ ""Name"": ""std_id"", ""Value"": ""111"" },
{ ""Name"": ""cust_id"", ""Value"": ""444"" }
]";
dynamic obj = new JObject(JArray.Parse(json)
.Select(t => new JProperty((string)t["Name"], t["Value"])));
从那里,您可以像访问匿名类型一样访问属性(假设您知道它们是什么):
Console.WriteLine(obj.std_id);
Console.WriteLine(obj.cust_id);
如果您不知道属性是什么,则可以像字典一样枚举它们:
foreach (var prop in obj)
{
Console.WriteLine(prop.Name + ": " + prop.Value);
}
小提琴: https : //dotnetfiddle.net/MRY2ny
var definition = new { Name = "" };
string json1 = @"{'Name':'James'}";
var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);
Console.WriteLine(customer1.Name);
string json2 = @"{'Name':'Mike'}";
var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition);
Console.WriteLine(customer2.Name);
来源http://www.newtonsoft.com/json/help/html/DeserializeAnonymousType.htm
我知道此解决方案并不完美,但它可用于您提供的示例,并返回类似于您示例中的paramObj
结果。
这个想法是创建一个自定义的Json转换器。
首先,让我们创建一个DTO类,以显示传入的JSON的名称-值项。
public class NameValueJsonItem
{
public string Name { get; set; }
public string Value { get; set; }
}
转换器实现:
public class DynamicJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token == null || token.Type != JTokenType.Array)
{
return null;
}
List<NameValueJsonItem> parsedJson = token.ToObject<List<NameValueJsonItem>>();
ExpandoObject result = new ExpandoObject();
foreach (NameValueJsonItem item in parsedJson)
{
if (!String.IsNullOrEmpty(item.Name))
{
(result as IDictionary<string, object>)[item.Name] = item.Value;
}
}
return result;
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
当然,如果需要,您可以通过在方法内部添加一些异常处理等来使其更加安全。
您可以像这样使用此转换器:
dynamic result = JsonConvert.DeserializeObject<dynamic>(json, new DynamicJsonConverter());
希望它会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.