简体   繁体   English

Newtonsoft JSON.net 反序列化错误,其中 JSON 中的字段更改顺序

[英]Newtonsoft JSON.net deserialization error where fields in JSON change order

This is a WCF service getting requests from android devices.这是一个从安卓设备获取请求的 WCF 服务。 Same request works from Lollipop devices, not from jellybean devices, because jellybean arranges the JSON differently on creation.相同的请求适用于 Lollipop 设备,而不适用于 jellybean 设备,因为 jellybean 在创建时对 JSON 的排列方式不同。

The exception:例外:

Unexpected token when deserializing object: String.反序列化对象时出现意外标记:字符串。 Path 'SearchFilters.config.$type', line 1, position 212.路径“SearchFilters.config.$type”,第 1 行,位置 212。

Non working Json:非工作 Json:

{
    "DeviceType": 2,
    "SearchFilters": {
        "config": {
            "$values": [
                {
                    "Collection": {
                        "DeviceType": 2
                    },
                    "Category": ""
                }
            ],
            "$type": "System.Collections.Generic.List`1[[Yoosh.SharedClasses.YooshConfig, YooshSharedClassesDll]], mscorlib"
        }
    },
    "RequestingUserId": "66666666-6666-6666-6666-666666666666",
    "APIKey": "xxx"
}

Working Json:工作JSON:

{
    "APIKey": "xxx",
    "DeviceType": 2,
    "RequestingUserId": "66666666-6666-6666-6666-666666666666",
    "SearchFilters": {
        "config": {
            "$type": "System.Collections.Generic.List`1[[Yoosh.SharedClasses.YooshConfig, YooshSharedClassesDll]], mscorlib",
            "$values": [
                {
                    "Category": "",
                    "Collection": {
                        "DeviceType": 2
                    }
                }
            ]
        }
    }
}

Some fields are in a different order.. Thats the only difference.有些字段的顺序不同。这是唯一的区别。

The C# class: C# 类:

public class QueryParameters 
{
    BaseParameters m_baseParameters;
    Guid m_gRequestingUserId;
    Dictionary<string, object> m_SearchFilters;

    [DataMember]
    public  string APIKey
    {
        get { return m_baseParameters.APIKey; }
        set { m_baseParameters.APIKey = value; }
    }

    [DataMember]
    public  BaseParameters.YooshDeviceType DeviceType
    {
        get { return m_baseParameters.DeviceType; }
        set { m_baseParameters.DeviceType = value; }
    }

    [DataMember]
    public  string DeviceId
    {
        get { return m_baseParameters.DeviceId; }
        set { m_baseParameters.DeviceId = value; }
    }

    [DataMember]
    public Guid RequestingUserId
    {
        get { return m_gRequestingUserId; }
        set { m_gRequestingUserId = value; }
    }

    [DataMember]
    public Dictionary<string, object> SearchFilters
    {
       get { return m_SearchFilters; }
        set { m_SearchFilters = value; }
    }
}

Json.net version: 6.0.8 Json.net 版本:6.0.8

Set JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead .设置JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead

According to the documentation :根据文档

This sample deserializes JSON with MetadataPropertyHandling set to ReadAhead so that metadata properties do not need to be at the start of an object.此示例反序列化 JSON,并将 MetadataPropertyHandling 设置为 ReadAhead,以便元数据属性不需要位于对象的开头。

 string json = @"{ 'Name': 'James', 'Password': 'Password1', '$type': 'MyNamespace.User, MyAssembly' }"; object o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, // $type no longer needs to be first MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead });

Note that this setting will impact performance .请注意,此设置会影响性能

Finally, when using TypeNameHandling , do take note of this caution from the Newtonsoft docs :最后,在使用TypeNameHandling ,请注意Newtonsoft 文档中的这一警告:

TypeNameHandling should be used with caution when your application deserializes JSON from an external source.当您的应用程序从外部源反序列化 JSON 时,应谨慎使用 TypeNameHandling。 Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.当使用 None 以外的值反序列化时,应使用自定义 SerializationBinder 验证传入类型。

For a discussion of why this may be necessary, see TypeNameHandling caution in Newtonsoft Json .有关为什么这可能是必要的讨论,请参阅Newtonsoft Json 中的 TypeNameHandling 警告

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM