我正在使用ASP Net Core 2.2
我将这个动态对象序列化
var stuff1 = new
{
Name = "John",
Surname = "Smith",
Addresses = new[] {
new { City = "New York", State = "NY"},
new { City = "Milano", State = "IT" }
};
var stuff1Serialized = JsonConvert.SerializeObject(stuff1)
这是序列化的对象:
{"Name":"John","Surname":"Smith"}
现在,我得到了这个字符串,并对其进行了反序列化
dynamic stuff1Deserialized = JsonConvert.DeserializeObject(stuff1Serialized);
我希望sutff1和stuff1Deseralized具有相同的结构,但是它们是不同的,为什么?
在立即窗口中:
stuff1.name
"Jhon"
stuff1Deserialized.Name
{John}
First: '((Newtonsoft.Json.Linq.JToken)stuff1Deserialized.Name).First' threw an exception of type 'System.InvalidOperationException'
HasValues: false
Last: '((Newtonsoft.Json.Linq.JToken)stuff1Deserialized.Name).Last' threw an exception of type 'System.InvalidOperationException'
Next: null
Parent: {"Name": "John"}
Path: "Name"
Previous: null
Root: {{
"Name": "John",
"Surname": "Smith"
}}
Type: String
Value: "John"
Results View: Expanding the Results View will enumerate the IEnumerable
我通过简单的DotLiquid模板使用该对象:
Hello {{Name}} {{Surname}}. Number of Addresses: {{Addresses.size}} - {{Addresses[0].City}} - {{Addresses[1].City}}
有了stuff1对象,我得到了预期的结果:
Hello John Smith. Number of Addresses: 2 - New York - Milano
使用stuff1Deserialized对象,我得到了以下结果:
Hello John Smith. Number of Addresses: 2 - -
答案 0 :(得分:3)
根据评论更新
我找到了一种方法:
1-对象动态样本:
dynamic dynamicStuff = new
{
Name = "John",
Surname = "Smith",
Obj = new { City = "New York", State = "NY" },// i add this to test object
Addresses = new[]
{
new { City = "New York", State = "NY"},
new { City = "Milano", State = "IT" }
}
};
2-序列化和反序列化以构建动态对象:
dynamic dynamicStuffDeSerialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dynamicStuff));
3-将dynamic
转换为JObject
,将Dictionary
对象转换为JObject
,并建立Dictionary
的{string,object},
Dictionary<string, object> keyValuePairs = ConvertJObject(JObject.FromObject(dynamicStuffDeSerialized));
private static Dictionary<string, object> ConvertJObject(JObject jObject)
{
Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
foreach (var property in jObject)
{
if (property.Value.Type == JTokenType.Array)
keyValuePairs.Add(property.Key, ConvertJArray(property.Value.Select(o=>(JObject)o)));
else if (property.Value.Type == JTokenType.Object)
keyValuePairs.Add(property.Key, ConvertJObject((JObject)property.Value));
else
keyValuePairs.Add(property.Key, property.Value.ToString());
}
return keyValuePairs;
}
private static List<Dictionary<string, object>> ConvertJArray(IEnumerable<JObject> jObjects)
{
return jObjects.Select(o => ConvertJObject(o)).ToList();
}
请注意,您可以使用ToObject
将JObject
转换为Dictionary
,但是它只是转换简单值而不是对象或数组,例如:
JObject jObject = JObject.FromObject(dynamicStuffDeSerialized);
Dictionary<string, object> dict = jObject.ToObject<Dictionary<string, object>>();
4-使用Hash.FromDictionary
而不是Hash.FromAnonymousObject
:
Template templatedynamicStuff = Template.Parse("Hello {{Name}} {{Surname}} City in Object {{Obj.City}}. Number of Addresses: {{Addresses.size}} - {{Addresses[0].City}} - {{Addresses[1].City}}");
string result = templatedynamicStuff.Render(Hash.FromDictionary(keyValuePairs));
请注意,我通过添加template
来更改了City in Object {{Obj.City}}
5-测试
Console.WriteLine(result);
6-结果:
Hello John Smith City in Object New York. Number of Addresses: 2 - New York - Milano
旧答案
根据 newtonsoft 文档,您可以使用DeserializeAnonymousType代替DeserializeObject
来进行反序列化匿名对象。但是DeserializeAnonymousType
需要definition
的 Anonymous 类型才能获得相同的 object 。
类似于以下代码:
var stuff1 = new
{
Name = "John",
Surname = "Smith"
};
var stuff1Serialized = JsonConvert.SerializeObject(stuff1);
var definition = new { Name = "", Surname = "" };
dynamic stuff1Deserialized = JsonConvert.DeserializeAnonymousType(stuff1Serialized, definition);
根据评论更新
您可以使用JObject
或ExpandoObject
来获取属性名称和值,例如以下代码:
dynamic stuff1 = new
{
Name = "John",
Surname = "Smith"
};
var stuff1Serialized = JsonConvert.SerializeObject(stuff1);
dynamic stuff1DeSerialized1 = JsonConvert.DeserializeObject(stuff1Serialized);
foreach (JProperty property in JObject.FromObject(stuff1DeSerialized1))
{
Console.WriteLine($"Key:{property.Name}, Value:{property.Value}");
}
ExpandoObject stuff1DeSerialized2 = JsonConvert.DeserializeObject<ExpandoObject>(stuff1Serialized, new ExpandoObjectConverter());
foreach(KeyValuePair<string, object> keyValue in stuff1DeSerialized2.ToList())
{
Console.WriteLine($"Key:{keyValue.Key}, Value:{keyValue.Value}");
}
我希望找到其他解决方案并与您分享。