简体   繁体   English

无法将当前 JSON 数组反序列化为响应为 xml 时的类型

[英]Cannot deserialize the current JSON array into type from when response is xml

I have the following response xml format from Microsoft:我有以下来自 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>
            <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&amp;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&amp;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&amp;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&amp;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&amp;w=272&amp;h=223&amp;o=f&amp;m=6&amp;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>

Sometimes happens that SuggestResults to be a single element instead of array.有时会发生 SuggestResults 是单个元素而不是数组。 So I created an JsonProperty as object and do trick in ParsedSuggestResult property.所以我创建了一个JsonProperty作为对象并在ParsedSuggestResult属性中做技巧。

I have the following class:我有以下课程:

public sealed class MsQueryXmlDetailResponse
    {

        public Suggestresponse SuggestResponse { get; set; }

        public class Suggestresponse
        {
            public string xmlnsxsd { get; set; }
            public string xmlnsxsi { get; set; }
            public string Query { get; set; }
            public Resultsets ResultSets { get; set; }
            public Errorsets ErrorSets { get; set; }
        }

        public class Resultsets
        {
            [JsonProperty("SuggestResults")]
            public object SuggestResultItems { get; set; }

            public Suggestresult[] ParsedSuggestResult {
                get
                {
                    if(SuggestResultItems is Suggestresult)
                    {
                        return new Suggestresult[] { SuggestResultItems as Suggestresult };
                    }

                    var result = SuggestResultItems as Suggestresult[];
                    if(result != null)
                    {
                        return result;
                    }

                    return new Suggestresult[] { JsonConvert.DeserializeObject<Suggestresult>(SuggestResultItems.ToString()) };
                }
            }
        }

        public class Suggestresult
        {
            public string Source { get; set; }
            public string FromCache { get; set; }
            public string Type { get; set; }
            public Suggests Suggests { get; set; }
        }

        public class Suggests
        {
            public Product[] Product { get; set; }
            public Term[] Term { get; set; }
        }

        public class Product
        {
            public string Curated { get; set; }
            public string Source { get; set; }
            public string Title { get; set; }
            public string Url { get; set; }
            public string ImageUrl { get; set; }
            public Metas Metas { get; set; }
        }

        public class Metas
        {
            public Meta[] Meta { get; set; }
        }

        public class Meta
        {
            public string Key { get; set; }
            public string Value { get; set; }
        }

        public class Term
        {
            public string Curated { get; set; }
            public string Txt { get; set; }
        }

        public class Errorsets
        {
            public Suggesterrorset SuggestErrorSet { get; set; }
        }

        public class Suggesterrorset
        {
            public string Source { get; set; }
            public string Message { get; set; }
        }
}

and I used Newtonsoft.Json to deserialize xml string format to a class (defined above):我使用 Newtonsoft.Json 将 xml 字符串格式反序列化为一个类(如上定义):

var xmldoc = new XmlDocument();
xmldoc.LoadXml(response);
var fromXml = JsonConvert.SerializeXmlNode(xmldoc);
MsQueryXmlDetailResponse data = JsonConvert.DeserializeObject<MsQueryXmlDetailResponse>(fromXml);

But I got:但我得到了:

Cannot deserialize the current JSON array into type because the type requires a JSON object (eg {"name":"value"}) to deserialize correctly.无法将当前 JSON 数组反序列化为类型,因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化。 To fix this error either change the JSON to a JSON object (eg {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (eg ICollection, IList) like List that can be deserialized from a JSON array.要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),例如可以从 JSON 数组反序列化。 JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. JsonArrayAttribute 也可以添加到类型以强制它从 JSON 数组反序列化。

What should I do here ?我应该在这里做什么? If I do SuggestResult[] instead of object and xml response contains one SuggestResult element then error occur again.如果我使用SuggestResult[]而不是object并且 xml 响应包含一个 SuggestResult 元素,则错误再次发生。

The serializer doesn't know what to convert those objects to so by default, it will return objects deriving from JToken .序列化程序不知道将这些对象转换为什么,因此默认情况下,它将返回从JToken派生的对象。 It knows nothing about the Suggesresult type for the SuggestResults property.它对SuggestResults属性的Suggesresult类型SuggestResults

You need to annotate that property to give a hint to what to deserialize to.您需要注释该属性以提示要反序列化的内容。 But given that it can be one or more items, you will have to create a converter for it.但考虑到它可以是一个或多个项目,您必须为它创建一个转换器。 Fortunately that should be simple to implement.幸运的是,这应该很容易实现。

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();
}

Then you could just provide a more appropriate type on the object itself.然后,您可以在对象本身上提供更合适的类型。

public class Resultsets
{
    [JsonProperty("SuggestResults")]
    [JsonConverter(typeof(SingleOrArrayJsonConverter<Suggestresult>))]
    public List<Suggestresult> SuggestResultItems { get; set; }

    public Suggestresult[] ParsedSuggestResult => SuggestResultItems.ToArray();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法反序列化当前JSON数组 - Cannot deserialize the current JSON array 无法反序列化当前JSON数组 - Cannot deserialize the current JSON array 从 API 响应 Cannot deserialize current JSON object - From API response Cannot deserialize the current JSON object 无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 - Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 如何解决“无法将当前的 JSON 数组反序列化为类型,因为该类型需要 JSON object 才能正确反序列化。” - How to solve “Cannot deserialize the current JSON array into type because the type requires a JSON object to deserialize correctly.” 无法反序列化当前 JSON object 因为该类型需要 JSON 数组(例如 [1,2,3])才能正确反序列化 - Cannot deserialize the current JSON object because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly 无法将JSON数组反序列化为类型 - Cannot deserialize JSON array into type “无法将当前JSON对象反序列化为类型 - "Cannot deserialize the current JSON object into type 从Firebase反序列化.netcore中的.json(无法反序列化当前JSON数组(例如[1,2,3])) - Deserialize .json in .netcore from firebase (Cannot deserialize the current JSON array (e.g. [1,2,3])) 无法反序列化当前JSON数组问题 - Cannot deserialize the current JSON array issue
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM