如果使用Json,则反序列化不适用于动态属性.NET属性



问题

大家好,

我正在尝试反序列化具有已知(静态)和未知(动态)属性的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_1my_dynamic_property_2

当我更改为[DataContract](用于[JsonObject])和System.Dynamic.DynamicObject0(用于[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"];

相关内容

  • 没有找到相关文章

最新更新