XML Запрос API возвращает «d3p1» для массивов или подклассов - PullRequest
0 голосов
/ 13 февраля 2020

Использование Postman, C#,. NET Framework 4.7

Я делаю GET-запрос от Postman с установленным для content-accept значением "application / xml" и my. NET Framework Web API ответит XML (великолепно!). Мне не нужно ничего сериализовать вручную, поскольку. NET Framework сериализует мой объект ответа, когда я возвращаю Request.CreateResponse(HttpStatusCode.OK, myResponse).

Однако, похоже, он включает в себя дополнительные вещи, с которыми я не знаком, и мне интересно можно ли их удалить через настройки Global.asax или аналогичные?

  • xmlns = "http://schemas.datacontract.org/2004/07/dto.MyModels" - это то, что я хотел бы удалить!
  • "d3p1" - это не то, с чем я столкнулся при создании XML. Могу ли я удалить его как-нибудь?
  • <error i:nil="true" /> всплывает, когда что-то ноль Можно ли просто быть или не появляться, когда оно пустое?

Итак, ответ XML выглядит так:

<SimpleResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/dto.MyModels">
    <error i:nil="true" />
    <result>
        <bookList xmlns:d3p1="http://schemas.datacontract.org/2004/07/dto.MyModels.Shared">
            <d3p1:Book>
                <d3p1:bookname>Book 1 Name</d3p1:bookname>
                <d3p1:serial>ZMeTaQ1kejh0mJYGHE4+1a4Y2juU6tMDd5zYDqN4tqI=</d3p1:serial>
                <d3p1:id>4</d3p1:id>

            </d3p1:Book>
            <d3p1:Book>
                <d3p1:bookname>Hello World</d3p1:bookname>
                <d3p1:serial>9lM16kho3bgsrG+wRh4ejtZjwrYJwp6FbRqnnZ4CJPA=</d3p1:serial>
                <d3p1:id>5</d3p1:id>
            </d3p1:Book>
            <d3p1:Book>
                <d3p1:bookname>Ding</d3p1:bookname>
                <d3p1:serial>XCqqKB+Wi3i4z6nN1Ry8IHtar6ogojjiqxMfvfgC0qc=</d3p1:serial>
                <d3p1:id>6</d3p1:id>
            </d3p1:Book>
        </bookList>
        <author xmlns:d3p1="http://schemas.datacontract.org/2004/07/dto.Models.Android.Shared">
            <d3p1:pictureId>0</d3p1:pictureId>
            <d3p1:websiteurl i:nil="true" />
            <d3p1:email i:nil="true" />
            <d3p1:name>Jo Blogs</d3p1:size>
            <d3p1:age>0</d3p1:size>
        </author>
    </result>
</SimpleResponse>

Мои классы выглядят примерно так :

public string error { get; set;}
public class SimpleResponse 
{
 public List<Book> bookList { get; set; }
 public Author author { get; set; }
}

public class Book
{
    public string bookname { get; set; }
    public string serial { get; set; }
    public int id { get; set; }
}

public class Author
{
    public string pictureId{ get; set; }
    public string websiteurl { get; set; }
    public string email { get; set; }
    public string name { get; set; }
    public int age { get; set; }
}

1 Ответ

1 голос
/ 13 февраля 2020

xmlns = "http://schemas.datacontract.org/2004/07/dto.MyModels" - это то, что я хотел бы удалить!
"d3p1" - это не то, с чем я столкнулся, когда создание XML. Можно ли как-нибудь удалить его?

Атрибуты:

оба XML объявления пространства имен . Первый устанавливает пространство имен XML по умолчанию для вашего документа XML; второй объявляет пространство имен, к которому принадлежат все дочерние элементы с предваряющим d3p1:.

Из выбранного пространства имен c очевидно, что вы используете DataContractSerializer для XML сериализации. Этот сериализатор назначает XML пространства имен в соответствии с правилами, описанными в Имена контрактов данных: пространства имен контрактов данных

По умолчанию любое данное пространство имен CLR (в формат Clr.Namespace) сопоставляется с пространством имен http://schemas.datacontract.org/2004/07/Clr.Namespace.. Чтобы переопределить это значение по умолчанию, примените атрибут ContractNamespaceAttribute ко всему модулю или сборке. В качестве альтернативы, для управления пространством имен контракта данных для каждого типа, установите свойство Пространство имен DataContractAttribute .

Поскольку вы не хотите XML Пространство имен для любого из ваших типов, первый вариант может показаться самым простым: применить следующие атрибуты к вашей сборке:

[assembly: ContractNamespaceAttribute("", ClrNamespace = "dto.MyModels")]
[assembly: ContractNamespaceAttribute("", ClrNamespace = "dto.MyModels.Shared")]
[assembly: ContractNamespaceAttribute("", ClrNamespace = "dto.Models.Android.Shared")]

В качестве альтернативы, вы можете применить атрибуты контракта данных к Ваши типы:

[DataContract(Name = "Book", Namespace = "")]
public class Book
{
    [DataMember]
    public string bookname { get; set; }
    [DataMember]
    public string serial { get; set; }
    [DataMember]
    public int id { get; set; }
}

Обратите внимание, что сериализация контракта данных opt-in , поэтому вам нужно будет применить [DataMember] к каждому члену, который будет сериализован.

В качестве последней альтернативы вы можете переключиться на использование XmlSerializer, которое не имеет пространства имен по умолчанию XML. Для этого вам нужно будет применить [XmlSerializerFormat] к вашему контракту на обслуживание, как показано в Ручное переключение на XmlSerializer .

<error i:nil="true" /> всплывает, когда что-то ноль. Можно ли просто быть или не отображаться, когда оно пустое?

Эти нулевые элементы можно удалить, установив DataMemberAttribute.EmitDefaultValue в элементах данных ссылочного типа как показано в этот ответ до Можно ли настроить DataContractSerializer так, чтобы он не создавал необязательные (т. е. Nullable <> и List <>) элементы в выходных данных XML? с помощью Даррен Кларк :

[DataContract(Name = "Book", Namespace = "")]
public class Book
{
    [DataMember(EmitDefaultValue = false)]
    public string bookname { get; set; }
    [DataMember(EmitDefaultValue = false)]
    public string serial { get; set; }
    [DataMember]
    public int id { get; set; }
}

В качестве альтернативы вы можете переключиться на XmlSerializer, который не выводит нулевые эталонные значения по умолчанию.

...