Why won't my ASP.Net Core Web API Controller return XML?

时间:2016-07-11 21:17:00

标签: xml asp.net-web-api asp.net-core asp.net-core-mvc

I have the following simple Web API controller:

    // GET: api/customers
    [HttpGet]
    public async Task<IActionResult> Get()
        {
        var customers = await uow.Users.GetAllAsync();
        var dto = customers.Select(p => new CustomerDto {Id = p.Id, Email = p.Email, UserName = p.UserName});
        return Ok(dto); // IEnumerable<CustomerDto>
        }

In Postman, I'm setting the Accept header to application/xml, but no matter what I try, I can only get JSON data back.

Postman screen shot

I read somewhere that in order to get XML, I must add [DataContract] and [DataMember] attributes to my DTO, which now looks like this:

[DataContract]
public class CustomerDto
    {
    [DataMember]
    public string Id { get; set; }

    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    [DataMember]
    public string Email { get; set; }

    [Required]
    [Display(Name = "Login Name")]
    [DataMember]
    public string UserName { get; set; }
    }

I've been at it several hours now and I'm just not seeing why it doesn't work. I've tried:

  • Making the action method synchronous and asynchronous
  • Returning the data directly, and setting the return type to IEnumerable<CustomerDto>
  • Converting the collection to an array instead of a list
  • Returning an IActionResult
  • Returning a single item, instead of a collection
  • I've verified that the Accept header is showing up in the request by examining it in the debugger.
  • Lots of "Googling with Bing" and reading various blogs
  • Creating a new WebAPI project from the template and seeing if there is any inspiration there (not really).

    I expect it's simple, but I can't see it...

8 个答案:

答案 0 :(得分:15)

Xml formatters are part of a separate package: Microsoft.AspNetCore.Mvc.Formatters.Xml

Add the above package and update your startup.cs like below:

services
    .AddMvc()
    .AddXmlDataContractSerializerFormatters();

OR

services
    .AddMvc()
    .AddXmlSerializerFormatters();

答案 1 :(得分:8)

对于Asp.Net Core 2.x,您基本上需要以下三点才能 返回 XML响应:

Startup.cs:

services
    .AddMvcCore(options => options.OutputFormatters.Add(new XmlSerializerOutputFormatter())

CustomerController.cs:

using Microsoft.AspNetCore.Mvc;

namespace WebApplication
{
    [Route("api/[controller]")]
    public class CustomerController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            var customer = new CustomerDto {Id = 1, Name = "John", Age = 45};
            return Ok(customer);
        }
    }
}

CustomerDto.cs:

namespace WebApplication
{
    public class CustomerDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

然后在请求中添加Accept“ application / xml”标头后,将返回XML格式的结果。

我必须为自己找到的一个非常重要的提示是,如果您的模型没有隐式的显式无参数构造函数,则响应将被编写为json。给出以下示例

namespace WebApplication
{
    public class CustomerDto
    {
        public CustomerDto(int id, string name, int age)
        {
            Id = id;
            Name = name;
            Age = age;
        }

         public int Id { get; }
         public string Name { get; }
         public int Age { get; }
    }
}

它将返回 json 。您应该为此模型添加

public CustomerDto()
{
}

这将再次返回 XML

答案 2 :(得分:5)

对于 asp.net core 2.x ,您可以配置 OutputFormatter

您可以尝试在startup.cs类的ConfigureServices方法中遵循以下代码段。

public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc(action =>
     {
         action.ReturnHttpNotAcceptable = true;
         action.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
     });

     //...
}

用于使用来自nuget的 Microsoft.AspNetCore.Mvc.Formatters 包中的 XmlDataContractSerializerOutputFormatter 引用。

现在它应该适用于 xml json

答案 3 :(得分:3)

对于 MVC 1.1 ,您需要添加包Microsoft.AspNetCore.Mvc.Formatters.Xml并编辑 Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => { options.RespectBrowserAcceptHeader = true; })
        .AddXmlSerializerFormatters()
        .AddXmlDataContractSeria‌​lizerFormatters();
}

现在您可以设置Accept Header:

XML:application/xml

JSON:application/json

答案 4 :(得分:1)

对于.net core 3.x,您可以如下使用

services.AddControllers(options=> {
            options.OutputFormatters.RemoveType(typeof(SystemTextJsonOutputFormatter));
            options.InputFormatters.RemoveType(typeof(SystemTextJsonInputFormatter));
            options.ReturnHttpNotAcceptable = true;
        }).AddXmlSerializerFormatters();

答案 5 :(得分:1)

以下解决方案很适合我。

Startup.cs

services.AddMvc()
       .AddXmlSerializerFormatters()
       .AddXmlDataContractSerializerFormatters();

YourController.cs

    [HttpGet]
    [Route("Get")]
    [Produces("application/xml")] // If you don't like to send Content-Type header
    public IActionResult Get()
    {
        try
        {                
            var user = _userManager.FindByNameAsync('user').Result;
            if (user != null)
            {
                if (!_userManager.CheckPasswordAsync(user, 'password').Result)
                {
                    return Unauthorized();
                }
                else
                {
                    var result = _services.GetDataFromService(Convert.ToInt64(2), start_date, end_date);
                    return Ok(result);
                }
            }
            else
            {
                return Unauthorized();
            }
        }
        catch (Exception ex)
        {
            return Unauthorized();
        }
    }

答案 6 :(得分:0)

对于Core 2.x版本,您唯一要做的就是在 Startup.cs 文件的 ConfigureServie方法中包含以下代码。

>
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
            .AddMvcOptions(o => o.OutputFormatters.Add(
              new XmlDataContractSerializerOutputFormatter()));
}

您需要引用 Microsoft.AspNetCore.Mvc.Formatters

答案 7 :(得分:0)

对于Core 2.x版本,您必须做两件事。首先,您需要在Startup.cs文件的ConfigureServices方法内添加以下代码。

services.AddMvc()
.AddMvcOptions(o => o.OutputFormatters.Add(
    new XmlDataContractSerializerOutputFormatter())
);

然后在Postman上,如下所示将Accept“ application / xml”标头添加到请求中。然后将返回XML格式的结果。

enter image description here