C# 当响应为xml时,无法从将当前JSON数组反序列化为类型
我从Microsoft获得以下响应xml格式:C# 当响应为xml时,无法从将当前JSON数组反序列化为类型,c#,arrays,xml,C#,Arrays,Xml,我从Microsoft获得以下响应xml格式: <SuggestResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Query>state of decay 2</Query> <ResultSets> <SuggestResults>
<SuggestResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Query>state of decay 2</Query>
<ResultSets>
<SuggestResults>
<Source>dcatall-products</Source>
<FromCache>false</FromCache>
<Type>product</Type>
<Suggests>
<Product>
<Curated>false</Curated>
<Source>Games</Source>
<Title>State of Decay 2</Title>
<Url>//www.microsoft.com/en-us/store/p/state-of-decay-2/9nt4x7p8b9nb</Url>
<ImageUrl>//store-images.s-microsoft.com/image/apps.47366.14425140369408817.dca0bcd1-c06c-4345-8a00-fe5bfaff3665.45f69514-da1a-43cd-a1ec-109fe5e54d24?w=150&h=150</ImageUrl>
<Metas>
<Meta>
<Key>BigCatalogId</Key>
<Value>9NT4X7P8B9NB</Value>
</Meta>
<Meta>
<Key>ProductType</Key>
<Value>Game</Value>
</Meta>
<Meta>
<Key>Icon</Key>
<Value>//store-images.s-microsoft.com/image/apps.47366.14425140369408817.dca0bcd1-c06c-4345-8a00-fe5bfaff3665.45f69514-da1a-43cd-a1ec-109fe5e54d24</Value>
</Meta>
<Meta>
<Key>ImageHeight</Key>
<Value>300</Value>
</Meta>
<Meta>
<Key>ImageWidth</Key>
<Value>300</Value>
</Meta>
<Meta>
<Key>ImageType</Key>
<Value>Logo</Value>
</Meta>
</Metas>
</Product>
<Product>
<Curated>false</Curated>
<Source>Games</Source>
<Title>State of Decay 2: Independence Pack</Title>
<Url>//www.microsoft.com/en-us/store/p/state-of-decay-2-independence-pack/9n0jhbm3618s</Url>
<ImageUrl>//store-images.s-microsoft.com/image/apps.19309.13920304356617547.62bf0ed6-7d21-4166-9bc0-99b6d7154bd1.e3af862c-7d10-4e9d-8f68-2c9a70d610b1?w=150&h=150</ImageUrl>
<Metas>
<Meta>
<Key>BigCatalogId</Key>
<Value>9N0JHBM3618S</Value>
</Meta>
<Meta>
<Key>ProductType</Key>
<Value>Durable</Value>
</Meta>
<Meta>
<Key>Icon</Key>
<Value>//store-images.s-microsoft.com/image/apps.19309.13920304356617547.62bf0ed6-7d21-4166-9bc0-99b6d7154bd1.e3af862c-7d10-4e9d-8f68-2c9a70d610b1</Value>
</Meta>
<Meta>
<Key>ImageHeight</Key>
<Value>1080</Value>
</Meta>
<Meta>
<Key>ImageWidth</Key>
<Value>1080</Value>
</Meta>
<Meta>
<Key>ImageType</Key>
<Value>BoxArt</Value>
</Meta>
</Metas>
</Product>
<Product>
<Curated>false</Curated>
<Source>Games</Source>
<Title>State Of Decay 2: Ultimate Edition</Title>
<Url>//www.microsoft.com/en-us/store/p/state-of-decay-2-ultimate-edition/9nsch45hz9hk</Url>
<ImageUrl>//store-images.s-microsoft.com/image/apps.50602.14365785075596216.2000000000013039869.e8c6dd03-ff3a-48fb-a8ad-479a95448240?w=150&h=150</ImageUrl>
<Metas>
<Meta>
<Key>BigCatalogId</Key>
<Value>9NSCH45HZ9HK</Value>
</Meta>
<Meta>
<Key>ProductType</Key>
<Value>Game</Value>
</Meta>
<Meta>
<Key>Icon</Key>
<Value>//store-images.s-microsoft.com/image/apps.50602.14365785075596216.2000000000013039869.e8c6dd03-ff3a-48fb-a8ad-479a95448240</Value>
</Meta>
<Meta>
<Key>ImageHeight</Key>
<Value>1080</Value>
</Meta>
<Meta>
<Key>ImageWidth</Key>
<Value>1080</Value>
</Meta>
<Meta>
<Key>ImageType</Key>
<Value>BoxArt</Value>
</Meta>
<Meta>
<Key>AppBgColor</Key>
<Value>#FFFFFF</Value>
</Meta>
</Metas>
</Product>
<Product>
<Curated>false</Curated>
<Source>Games</Source>
<Title>State of Decay 2: Doomsday Pack</Title>
<Url>//www.microsoft.com/en-us/store/p/state-of-decay-2-doomsday-pack/9pcqkkwf0zwp</Url>
<ImageUrl>//store-images.s-microsoft.com/image/apps.6519.14169313509850372.ade11659-c080-431a-9d6b-6933c4264efb.20f0ebab-bd4f-41c3-a514-7f9347266072?w=150&h=150</ImageUrl>
<Metas>
<Meta>
<Key>BigCatalogId</Key>
<Value>9PCQKKWF0ZWP</Value>
</Meta>
<Meta>
<Key>ProductType</Key>
<Value>Durable</Value>
</Meta>
<Meta>
<Key>Icon</Key>
<Value>//store-images.s-microsoft.com/image/apps.6519.14169313509850372.ade11659-c080-431a-9d6b-6933c4264efb.20f0ebab-bd4f-41c3-a514-7f9347266072</Value>
</Meta>
<Meta>
<Key>ImageHeight</Key>
<Value>1080</Value>
</Meta>
<Meta>
<Key>ImageWidth</Key>
<Value>1080</Value>
</Meta>
<Meta>
<Key>ImageType</Key>
<Value>BoxArt</Value>
</Meta>
</Metas>
</Product>
<Product>
<Curated>false</Curated>
<Source>Devices</Source>
<Title>State of Decay 2 for Xbox One</Title>
<Url>//www.microsoft.com/en-us/store/p/state-of-decay-2-for-xbox-one/8p2fgp3bf0fc</Url>
<ImageUrl>//img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1Tc21?ver=3d93&w=272&h=223&o=f&m=6&f=jpg</ImageUrl>
<Metas>
<Meta>
<Key>BigCatalogId</Key>
<Value>8P2FGP3BF0FC</Value>
</Meta>
<Meta>
<Key>ProductType</Key>
<Value>Devices</Value>
</Meta>
<Meta>
<Key>Icon</Key>
<Value>https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1Tc21?ver=3d93</Value>
</Meta>
<Meta>
<Key>ImageHeight</Key>
<Value>1540</Value>
</Meta>
<Meta>
<Key>ImageWidth</Key>
<Value>1189</Value>
</Meta>
<Meta>
<Key>ImageType</Key>
<Value>tile</Value>
</Meta>
</Metas>
</Product>
</Suggests>
</SuggestResults>
<SuggestResults>
<Source>microsoft-terms</Source>
<FromCache>false</FromCache>
<Type>term</Type>
<Suggests>
<Term>
<Curated>false</Curated>
<Txt>state of decay year one survival edition</Txt>
</Term>
<Term>
<Curated>false</Curated>
<Txt>state of decay year one survival edition for xbox one</Txt>
</Term>
<Term>
<Curated>false</Curated>
<Txt>state of decay for xbox 360 download code</Txt>
</Term>
</Suggests>
</SuggestResults>
</ResultSets>
<ErrorSets>
<SuggestErrorSet>
<Source>iris-products</Source>
<Message>Code: 2040. Message: Demand source returns error (Name: GN_ps, Error: No eligible content.).</Message>
</SuggestErrorSet>
</ErrorSets>
</SuggestResponse>
我使用Newtonsoft.Json将xml字符串格式反序列化为一个类(定义见上文):
var xmldoc=new XmlDocument();
LoadXml(响应);
var fromXml=JsonConvert.SerializeXmlNode(xmldoc);
MsQueryXmlDetailResponse data=JsonConvert.DeserializeObject(fromXml);
但我得到了:
无法将当前JSON数组反序列化为类型,因为类型
需要一个JSON对象(例如{“name”:“value”})来反序列化
正确地要修复此错误,请将JSON更改为JSON对象
(例如{“name”:“value”})或将反序列化类型更改为数组或
实现集合接口的类型(例如ICollection、,
IList)类似于可以从JSON数组反序列化的列表。
还可以将JsonArrayAttribute添加到类型中,以强制它
从JSON数组反序列化
我在这里该怎么办?如果我使用
SuggestResult[]
而不是object
,并且xml响应包含一个SuggestResult元素,则再次发生错误。序列化程序不知道将这些对象转换成什么,因此默认情况下,它将返回从JToken
派生的对象。它不知道suggestresult
属性的suggestresult
类型
您需要对该属性进行注释,以提示要反序列化的内容。但考虑到它可以是一个或多个项目,您必须为它创建一个转换器。幸运的是,这应该很容易实现
class SingleOrArrayJsonConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(List<T>);
public override bool CanRead => true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
switch (token.Type)
{
case JTokenType.Array:
return ToObject<List<T>>(token);
default:
return new List<T> { ToObject<T>(token) };
}
}
private TObj ToObject<TObj>(JToken token) => token.ToObject<TObj>();
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}
class SingleOrrayJSONConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)=>objectType==typeof(列表);
public override bool CanRead=>true;
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var token=JToken.Load(读卡器);
开关(token.Type)
{
案例JTokenType.Array:
返回到对象(令牌);
违约:
返回新列表{ToObject(token)};
}
}
私有TObj-tobject(JToken-token)=>token.tobject();
公共覆盖boolcanwrite=>false;
public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)=>throw new NotImplementedException();
}
然后您可以在对象本身上提供一个更合适的类型
public class Resultsets
{
[JsonProperty("SuggestResults")]
[JsonConverter(typeof(SingleOrArrayJsonConverter<Suggestresult>))]
public List<Suggestresult> SuggestResultItems { get; set; }
public Suggestresult[] ParsedSuggestResult => SuggestResultItems.ToArray();
}
公共类结果集
{
[JsonProperty(“SuggestResults”)]
[JsonConverter(类型(SingleOrrayJSONConverter))]
公共列表SuggestResultItems{get;set;}
public Suggestresult[]ParsedSuggestResult=>SuggestResultItems.ToArray();
}
您可以做的第一件事是检查fromXml
中的JSON字符串,找出它与您的对象模型不一致的地方…与其从XML转换为JSON并使用JSON反序列化,为什么不直接将XML反序列化到您的类实例中呢?如果我得到SuggestResult数组,会发生什么?如果我得到SuggestResult的一个元素,会发生什么?将被视为包含一个元素的数组?如果使用包含一个SuggestResult的XML为代码提供数据,为什么不试试看会发生什么情况?我得到了
这是不应该的。。。
class SingleOrArrayJsonConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(List<T>);
public override bool CanRead => true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
switch (token.Type)
{
case JTokenType.Array:
return ToObject<List<T>>(token);
default:
return new List<T> { ToObject<T>(token) };
}
}
private TObj ToObject<TObj>(JToken token) => token.ToObject<TObj>();
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}
public class Resultsets
{
[JsonProperty("SuggestResults")]
[JsonConverter(typeof(SingleOrArrayJsonConverter<Suggestresult>))]
public List<Suggestresult> SuggestResultItems { get; set; }
public Suggestresult[] ParsedSuggestResult => SuggestResultItems.ToArray();
}