简而言之,我正在尝试反序列化来自Bing Maps地理编码REST API的JSON响应,
我创建了我的响应类,现在当我尝试实际反序列化响应时,出现以下错误:
不应使用数据协定名称为“ {1}:{2}”的类型“ {0}”。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型的列表中- 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型的列表中。
它试图反序列化这行JSON,但失败:
"__type": "Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1",
我的回应类看起来像这样
[DataContract] public class GeoResponse { [DataMember(Name = "statusDescription")] public string StatusDescription { get; set; } [DataMember(Name = "statusCode")] public string StatusCode { get; set; } [DataMember(Name = "resourceSets")] public ResourceSet[] resourceSets { get; set; } [DataContract] public class ResourceSet { [DataMember(Name = "__type", IsRequired=false)] public string type { get; set; } [DataMember(Name = "estimatedTotal")] public string EstimatedTotal { get; set; } [DataMember(Name = "resources")] public List<Resources> resources { get; set; } [DataContract] public class Resources { [DataMember(Name = "name")] public string Name { get; set; } [DataMember(Name = "point")] public Point point { get; set; } [DataContract] public class Point { [DataMember(Name = "type")] public string Type { get; set; } [DataMember(Name = "coordinates")] public string[] Coordinates { get; set; } } [DataMember(Name = "address")] public Address address { get; set; } [DataContract] public class Address { [DataMember(Name = "addressLine")] public string AddressLine { get; set; } [DataMember(Name = "countryRegion")] public string CountryRegion { get; set; } [DataMember(Name = "formattedAddress")] public string FormattedAddress { get; set; } [DataMember(Name = "locality")] public string Locality { get; set; } [DataMember(Name = "postalCode")] public string PostalCode { get; set; } } [DataMember(Name = "confidence")] public string Confidence { get; set; } [DataMember(Name = "entityType")] public string EntityType { get; set; } } } } }
我用来反序列化JSON响应的方法:
private static GeoResponse CallGeoWS(string address) { string url = string.Format( "http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}", HttpUtility.UrlEncode(address), bingkey ); var request = (HttpWebRequest)HttpWebRequest.Create(url); request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(GeoResponse)); var res = (GeoResponse)serializer.ReadObject(request.GetResponse().GetResponseStream()); return res; }
首先,请注意,您引用的方法(http://dev.virtualearth.net/REST/v1/Locations?q=Wiertzstraat+43+1047+Brussel&key=BingMapsKey)会产生不同的响应您正在尝试使用DataContract类进行映射。此处描述了响应:http : //msdn.microsoft.com/en- us/library/ff701711.aspx
我已经为该响应创建了一个DataContract:
[数据合同] 公共类LocationQueryResponse { [DataMember] 公共字符串authenticationResultCode {get; 组; } [DataMember] 公共字符串brandLogoUri {get; 组; } [DataMember] 公共字符串版权{ 组; } [DataMember] 公共字符串statusCode {get; 组; } [DataMember] 公共字符串statusDescription {get; 组; } [DataMember] 公共字符串traceId { 组; } [DataMember] 公共ResourceSet [] resourceSets {get; 组; } [数据合同] 公共类ResourceSet { [DataMember] public int EstimateTotal {get; 组; } [DataMember] 公共资源[]资源{ 组; } [DataContract(Namespace =“ http://schemas.microsoft.com/search/local/ws/rest/v1",Name="Location”)] 公共类资源 { [DataMember] 公共字符串__type {get; 组; } [DataMember] public double [] bbox {get; 组; } [DataMember] 公共字符串名称{get; 组; } [DataMember] 公共点{ 组; } [数据合同] 公共课点 { [DataMember] 公共字符串类型{get; 组; } [DataMember] 公共字符串[]坐标{ 组; } } [DataMember] 公共地址地址{get; 组; } [数据合同] 公共课地址 { [DataMember] 公共字符串addressLine {get; 组; } [DataMember] 公共字符串adminDistrict {get; 组; } [DataMember] 公共字符串adminDistrict2 {get; 组; } [DataMember] 公共字符串countryRegion {get; 组; } [DataMember] 公共字符串formattedAddress { 组; } [DataMember] 公共字符串局部性{ 组; } [DataMember] 公共字符串postalCode {get; 组; } } [DataMember] 公共字符串置信度{ 组; } [DataMember] 公共字符串实体类型{ 组; } } } }
最初,即使我创建了正确的DataContract,它也无法正常工作,并且会生成与您提出的异常相同的异常。经过一些研究,我发现“ __type”字段对于DataContractJsonSerializer具有特殊的含义,表示对象应反序列化的类型。为了完成这项工作,我在Name类的DataContract属性中添加了Name和Namespace属性(请在上面检查代码)。
我对WCF和JSON有相当的经验,以前从未遇到过此问题。它似乎是一个晦涩难懂的地方,__ type字段似乎不符合标准,而是Microsoft特定的功能。令人讨厌的是,__type字段似乎仅在某些特定情况下存在。例如,如果在JSON文档中您之前有空白,则反序列化器将忽略它并且不会引发任何异常。我最初用于测试的文档中有空白,这就是为什么此时我没有出错的原因。
希望这个人最终有所帮助。:)