问题
大家好,
我正在尝试反序列化具有已知(静态)和未知(动态)属性的Json字符串。为此,我使用Json。NET和CCD_ 1。在我的第一次尝试中,我使用了Json。NET特定的序列化属性来配置(反)序列化程序。但是,在这种情况下,Json字符串中的动态属性不会被反序列化。但当我换成母语时。NET属性([DataContract]
和[DataMember]
),动态属性被反序列化,我可以在创建的动态对象中访问它们。
这种行为是故意的吗?我错过了Json的任何配置吗。NET属性以获得相同的反序列化行为?
如有任何澄清,我们将不胜感激!
详细信息
在这里,我将提供实现的详细信息(使用Json.NET属性)。我正在使用。NET 4.5和Json。NET 6.0.2
因为我有多种具有静态和动态属性的消息类型,所以我引入了一个基类,它实现了动态处理属性:
[JsonObject]
internal abstract class DynamicMessage : DynamicObject
{
[JsonProperty]
public Dictionary<string, object> dynamicProperties = new Dictionary<string, object();
public override bool TryGetMember(GetMemberBinder binder, out object result) {...}
public override bool TrySetMember(SetMemberBinder binder, object value) {...}
}
具体的子类如下:
[JsonObject]
internal class ItemMessage : DynamicMessage
{
[JsonPropertyAttribute(PropertyName = "id")]
internal long Id;
[JsonPropertyAttribute(PropertyName = "parent_item");
internal long ParentItemId;
...
}
我尝试反序列化如下字符串:
jsonString = @{'id':1,
'parent_item':5,
'my_dynamic_property_1' : 1337,
'my_dynamic_property_2' : 'my_dynamic_property_2'}
JsonSerializer serializer = new JsonSerializer();
dynamic itemMessage = serializer.Deserialize<ItemMessage>(new JsonTextReader(jsonString));
正如我在开头指出的,如果我使用属性[JsonObject]
和[JsonProperty]
,则所有静态属性都会正确地反序列化并绑定到POCO属性,,但我缺少动态属性my_dynamic_property_1
和my_dynamic_property_2
当我更改为[DataContract]
(用于[JsonObject]
)和System.Dynamic.DynamicObject
0(用于[JsonProperty]
)时,Json中的动态属性也将被反序列化,我可以调用
itemMessage.my_dynamic_property_1; //=1337
itemMessage.my_dynamic_property_2; //="my_dynamic_property_2"
[JsonProperty]
始终将JSON中的单个属性绑定到类中的单个成员。不能使用它将多个JSON属性绑定到一个字典。这样不行。
然而,Json。Net确实有一个[JsonExtensionData]
属性,它可以按照您想要的方式工作。试试这个:
[JsonObject]
internal abstract class DynamicMessage : DynamicObject
{
[JsonExtensionData]
public Dictionary<string, object> dynamicProperties =
new Dictionary<string, object>();
...
}
这可能不是您想要的,但您总是可以反序列化到字典中。
var jsonString = @"{'id':1,
'parent_item':5,
'parent_details':{'name': 'parent_name', 'description': 'parent description'},
'array':[1,2,3,4,5,6,7],
'my_dynamic_property_1' : 1337,
'my_dynamic_property_2' : 'my_dynamic_property_2'}";
Dictionary<string, dynamic> values = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
我添加了一个嵌套对象,这样你就可以看到它仍然反序列化到另一个具有动态值的字典中,以保持所有内容的类型正确。出于同样的目的,我还添加了一组整数。
你可以这样访问你的动态属性:
values[my_dynamic_property_1];
尽管我建议铸造已知的类型,比如:
var prop1 = (int)values["my_dynamic_property_1"];
至于嵌套对象,您可以直接访问成员,如下所示:
var parentDescription = values["parent_details"]["name"];