Сериализация обобщенной модели c # в xml в .net core 3.0 - PullRequest
0 голосов
/ 07 ноября 2019

Я использую .net core 3.0 для создания веб-API. Я хочу сериализовать универсальную модель в XML. Но по умолчанию он сериализует общую модель только в JSON.

Когда я попытался сериализовать простую модель в XML, она правильно сериализовалась в XML.

В зависимости от пройденных заголовков, я хочу сериализовать модель. Вот что я делал до сих пор:

В файле startup.cs:

services.AddControllers(options =>{
        options.RespectBrowserAcceptHeader = true; // false by default
    }).
    AddXmlSerializerFormatters().

Ниже приведен пример кода:

Моя общая модель:

public class ApiResponseModel<T>
{
    public int ErrorCode { get; set; }
    public string ErrorMessage { get; set; }
    public T Data { get; set; }

    public ApiResponseModel(int errorCode, string errorMessage, T data)
    {
        this.ErrorCode = errorCode;
        this.ErrorMessage = errorMessage;
        this.Data = data;
    }
}

Действие для возврата данных:

[HttpGet]
public async Task<IActionResult> Get()
{
    IEnumerable<RoleDTO> roleList = null;
    roleList = await _repository.RoleRepository.GetAllRolesAsync();
    var data = new ApiResponseModel<IEnumerable<RoleDTO>>(200, "Success", roleList);
    return Ok(data);
}

Этот ответ JSON, хотя заголовок Accept указан как application/xml.

Но если я просто верну roleListон дает ответ в формате XML.

[HttpGet]
public async Task<IActionResult> Get()
{
    IEnumerable<RoleDTO> roleList = null;
    roleList = await _repository.RoleRepository.GetAllRolesAsync();
    return Ok(roleList);
} 

Как я могу получить ответ XML и для универсальных моделей?

1 Ответ

0 голосов
/ 08 ноября 2019

Существует две причины:

  1. Ваш ApiResponseModel<T> не имеет конструктора без параметров.
  2. Вы используете XmlSerializer на AddXmlSerializerFormatters() (вместо XML DataContractSerializer), который не позаботится о сериализации IEnumerable<T> по умолчанию.

Чтобы устранить эту проблему, добавьте конструктор без параметров:

public class ApiResponseModel<T>
{
    public int ErrorCode { get; set; }
    public string ErrorMessage { get; set; }
    public T Data { get; set; }
    <b>public ApiResponseModel() { }</b>       // add a parameterless constructor

    public ApiResponseModel(int errorCode, string errorMessage, T data)
    {
        this.ErrorCode = errorCode;
        this.ErrorMessage = errorMessage;
        this.Data = data;
    }
}

И рассмотрите возможность добавления XML DataContractSerializerсредства форматирования, чтобы позаботиться о сериализации IEnumerable<T>:

services.AddControllersWithViews(opts =>{
    opts.RespectBrowserAcceptHeader = true;
})
<b>.AddXmlDataContractSerializerFormatters()</b>
.AddXmlSerializerFormatters()
...