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

Shy*_*leg 10 c# json.net

这是从Android设备获取请求的WCF服务.相同的请求适用于Lollipop设备,而不是来自软糖设备,因为软糖在创建时以不同方式排列JSON.

例外:

反序列化对象时出现意外的标记:String.路径'SearchFilters.config.$ type',第1行,第212位.

不工作的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"
}
Run Code Online (Sandbox Code Playgroud)

工作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
                    }
                }
            ]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有些字段的顺序不同.这是唯一的区别.

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

Json.net版本:6.0.8

dbc*_*dbc 13

设置JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead.

根据文件:

此示例将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
});
Run Code Online (Sandbox Code Playgroud)

请注意,此设置会影响性能.

最后,在使用时TypeNameHandling,请注意Newtonsoft文档中的这一注意事项:

当您的应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling.使用非None以外的值进行反序列化时,应使用自定义SerializationBinder验证传入类型.

有关可能需要这样做的讨论,请参阅Newtonsoft Json中的TypeNameHandling警告.