gpt4 book ai didi

c# - 在数据成员 "__type"上反序列化 JSON 时出现问题

转载 作者:太空狗 更新时间:2023-10-29 17:35:21 25 4
gpt4 key购买 nike

简而言之,我正在尝试反序列化来自 Bing Maps Geocoding 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:

[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 文档中前面有空格,反序列化器将忽略它并且不会抛出任何异常。我最初用于测试的文档中有这样一个空白区域,这就是我当时没有收到错误的原因。

希望这篇文章最终有所帮助。 :)

关于c# - 在数据成员 "__type"上反序列化 JSON 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4115037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com