Ent*_*ice 9 c# serialization json visual-studio
简而言之,我正在尝试从Bing Maps Geocoding REST API反序列化JSON响应,
我创建了我的响应类,现在当我试图实际反序列化响应时,我收到以下错误:
不期望输入数据合同名称为"{1}:{2}"的"{0}".考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中.
它试图反序列化这一行JSON,并失败:
"__type": "Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1",
Run Code Online (Sandbox Code Playgroud)
我的响应类看起来像这样
[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; }
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的方法我用来反序列化我的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;
}
Run Code Online (Sandbox Code Playgroud)
Flo*_*scu 20
首先,请注意您引用的方法(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:
[DataContract]
public class LocationQueryResponse
{
[DataMember]
public string authenticationResultCode { get; set; }
[DataMember]
public string brandLogoUri { get; set; }
[DataMember]
public string copyright { get; set; }
[DataMember]
public string statusCode { get; set; }
[DataMember]
public string statusDescription { get; set; }
[DataMember]
public string traceId { get; set; }
[DataMember]
public ResourceSet[] resourceSets { get; set; }
[DataContract]
public class ResourceSet
{
[DataMember]
public int estimatedTotal { get; set; }
[DataMember]
public Resource[] resources { get; set; }
[DataContract(Namespace = "http://schemas.microsoft.com/search/local/ws/rest/v1", Name="Location")]
public class Resource
{
[DataMember]
public string __type { get; set; }
[DataMember]
public double[] bbox { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public Point point { get; set; }
[DataContract]
public class Point
{
[DataMember]
public string type { get; set; }
[DataMember]
public string[] coordinates { get; set; }
}
[DataMember]
public Address address { get; set; }
[DataContract]
public class Address
{
[DataMember]
public string addressLine { get; set; }
[DataMember]
public string adminDistrict { get; set; }
[DataMember]
public string adminDistrict2 { get; set; }
[DataMember]
public string countryRegion { get; set; }
[DataMember]
public string formattedAddress { get; set; }
[DataMember]
public string locality { get; set; }
[DataMember]
public string postalCode { get; set; }
}
[DataMember]
public string confidence { get; set; }
[DataMember]
public string entityType { get; set; }
}
}
}
首先,即使我创建了正确的DataContract,它也不起作用,并且它生成了与您呈现的相同的异常.经过一些研究后,我发现"__type"字段对DataContractJsonSerializer有特殊含义,表示对象应反序列化的类型.为了完成这项工作,我将Name和Namespace属性添加到Resource类的DataContract属性中(请检查上面的代码).
我对WCF和JSON有很多经验,之前从未遇到过这个问题.它似乎是一个相当模糊的,__type字段似乎不符合标准,而是Microsoft特定的功能.非常令人讨厌的是__type字段似乎只在某些特定情况下.例如,如果在JSON文档中您之前有空格,则反序列化器会忽略它并且不会抛出任何异常.我在最初用于测试的文档中有这样的空白区域,这就是为什么我在那时没有得到错误.
希望这个终于有所帮助.:)