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

这是从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" } 

工作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 } } ] } } } 

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

C#类:

 public class QueryParameters { BaseParameters m_baseParameters; Guid m_gRequestingUserId; Dictionary 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 SearchFilters { get { return m_SearchFilters; } set { m_SearchFilters = value; } } } 

Json.net版本:6.0.8

设置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 }); 

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

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

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

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