Невозможно десериализовать список в ответе XML с помощью ReadAsAsync <T> - PullRequest
0 голосов
/ 06 марта 2019

[Обновление: этот вопрос отличается от предложенного дубликата, потому что этот вопрос о десериализации XML, и объяснение проблемы и решения по нему более понятно, поскольку я включил полный исходный код.]

Я пытаюсь прочитать и впоследствии манипулировать ответом из веб-API.Его ответ выглядит так:

<MYAPI xsi:noNamespaceSchemaLocation="MYAPI.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <MySite Resource="some resource name">
       <Name>some name</Name>
       <URL>some url</URL>
       <SecondName>Describes something</SecondName>
   </MySite>
   ... A lot of these <MySite>...</MySite> are there         

   <SomeOtherSite Resource="some resource name">
       <Name>some name</Name>
       <URL>some url</URL>
   </SomeOtherSite>
</MYAPI>

SomeOtherSite не повторяется, и только один из них появляется в конце ответа.Но MySite - это то, что повторяется.Я смоделировал класс для этого XML-ответа как:

public class MYAPI
{
    public List<MySite> MySite { get; set; }
    public SomeOtherSite SomeOtherSite { get; set; }
}

public class MySite
{
    public string Name { get; set; }
    public string URL { get; set; }
    public string SecondName { get; set; }
}

public class SomeOtherSite
{
    public string Name { get; set; }
    public string URL { get; set; }
}

И это мой код:

static void Main()
{
    var handler = new HttpClientHandler();
    handler.Credentials = new NetworkCredential("MyUsername", "MyPassword");

    var client = new HttpClient(handler);
    client.BaseAddress = new Uri("https://sitename.com:PortNumber/");

    var formatters = new List<MediaTypeFormatter>() 
    {
        new XmlMediaTypeFormatter(){ UseXmlSerializer = true } 
    };

    var myApi = new MYAPI();
    HttpResponseMessage response = client.GetAsync("/api/mysites").Result;

    if (response.IsSuccessStatusCode)
    {

        myApi = response.Content.ReadAsAsync<MYAPI>(formatters).Result;
    }
}

Теперь myApi имеет объект только для SomeOtherSite, носписок для MySite пуст.Кто-нибудь, скажите, пожалуйста, как мне правильно десериализовать этот ответ?Должен ли я создавать пользовательский медиа форматер?Кстати, я понятия не имею.

Не могли бы вы также рассказать мне, как смоделировать атрибут Resource, приходящий в ответ?

И я ничего не могу изменить вСервер WebAPI.Мне просто нужно извлечь данные из него и использовать его в другом месте.

Большое спасибо!

1 Ответ

0 голосов
/ 07 марта 2019

Я решил это после некоторого действительно хорошего указания: https://stackoverflow.com/users/1124565/amura-cxg Большое спасибо!

Решением было аннотировать все свойства с помощью XMLAttributes.И это правильно десериализовало ответ.А что касается атрибута Resource, все, что мне было нужно, это [XmlAttribute(AttributeName="Resource")]

Остальная часть исходного кода работает как есть.

[XmlRoot(ElementName="MYAPI")]
public class MYAPI 
{
    [XmlElement(ElementName="MySite")]
    public List<MySite> MySite { get; set; }

    [XmlElement(ElementName="SomeOtherSite")]
    public SomeOtherSite SomeOtherSite { get; set; }
}

public class MySite 
{
    [XmlElement(ElementName="Name")]
    public string Name { get; set; }

    [XmlElement(ElementName="URL")]
    public string URL { get; set; }

    [XmlElement(ElementName="SecondName")]
    public string SecondName { get; set; }

    [XmlAttribute(AttributeName="Resource")]
    public string Resource { get; set; }
}

Плюс, мне не нужно было никакого специального средства форматирования медиа.И из одного из сообщений https://stackoverflow.com/users/1855967/elisabeth я узнал, что мы не должны касаться сгенерированного файла из инструмента xsd.exe.Поэтому я явно настроил использование XmlSerializer вместо DataContractSerializer, используемого по умолчанию:

var formatters = new List<MediaTypeFormatter>() 
    {
        new XmlMediaTypeFormatter(){ UseXmlSerializer = true } 
    };
...