问题描述
这是一个从安卓设备获取请求的 WCF 服务.相同的请求适用于 Lollipop 设备,而不适用于 jellybean 设备,因为 jellybean 在创建时对 JSON 的排列方式不同.
This is a WCF service getting requests from android devices. Same request works from Lollipop devices, not from jellybean devices, because jellybean arranges the JSON differently on creation.
例外:
反序列化对象时出现意外标记:字符串.路径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
}
}
]
}
}
}
某些字段的顺序不同.这是唯一的区别.
Some fields are in a different order.. Thats the only difference.
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 版本:6.0.8
Json.net version: 6.0.8
推荐答案
设置<代码>JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead.
根据文档:
此示例反序列化 JSON 并将 MetadataPropertyHandling 设置为 ReadAhead,以便元数据属性不需要位于对象的开头.
This sample deserializes JSON with MetadataPropertyHandling set to ReadAhead so that metadata properties do not need to be at the start of an object.
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 文档:
Finally, when using TypeNameHandling
, do take note of this caution from the Newtonsoft docs:
当您的应用程序从外部源反序列化 JSON 时,应谨慎使用 TypeNameHandling.使用 None 以外的值反序列化时,应使用自定义 SerializationBinder 验证传入类型.
TypeNameHandling should be used with caution when your application deserializes JSON from an external source. Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.
有关为什么这可能是必要的讨论,请参阅Newtonsoft Json 中的 TypeNameHandling 警告.
For a discussion of why this may be necessary, see TypeNameHandling caution in Newtonsoft Json.
这篇关于Newtonsoft JSON.net 反序列化错误,其中 JSON 中的字段更改顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!