为什么我的ASP.Net核心Web API控制器不会返回XML?

Tim*_*ong 17 xml asp.net-web-api asp.net-core-mvc asp.net-core

我有以下简单的Web API控制器:

    // 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>
        }
Run Code Online (Sandbox Code Playgroud)

在Postman中,我将Accept标头设置为application/xml,但无论我尝试什么,我都只能获得JSON数据.

邮差屏幕截图

我在某处读到,为了获取XML,我必须添加[DataContract][DataMember]属性到我的DTO,现在看起来像这样:

[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; }
    }
Run Code Online (Sandbox Code Playgroud)

我已经在这几个小时了,我只是没有看到为什么它不起作用.我试过了:

  • 使action方法同步和异步
  • 直接返回数据,并将返回类型设置为 IEnumerable<CustomerDto>
  • 将集合转换为数组而不是列表
  • 回来了 IActionResult
  • 返回单个项目,而不是集合
  • 我已经通过在调试器中检查它来验证Accept头是否出现在请求中.
  • 大量"用Bing搜索"和阅读各种博客
  • 从模板创建一个新的WebAPI项目,看看是否有任何灵感(不是真的).

    我希望它很简单,但我看不到它......

Kir*_*lla 21

Xml格式化程序是单独包的一部分: Microsoft.AspNetCore.Mvc.Formatters.Xml

添加上面的包并更新您的startup.cs如下:

services
    .AddMvc()
    .AddXmlDataContractSerializerFormatters();
Run Code Online (Sandbox Code Playgroud)

要么

services
    .AddMvc()
    .AddXmlSerializerFormatters();
Run Code Online (Sandbox Code Playgroud)

  • 最新版本的asp.net核心似乎不存在这些方法! (3认同)
  • @TimLong:您可能必须在 MSDN 中查找该信息。 (2认同)
  • 在mvc 1.1中我需要:`services.AddMvc(options => {options.RespectBrowserAcceptHeader = true;}).AddXmlSerializerFormatters().AddXmlDataContractSerializerFormatters();`或者它总是会给我json (2认同)

Roo*_*gen 12

对于Asp.Net Core 2.x,您基本上需要这3件事来返回 XML响应:

Startup.cs:

services
    .AddMvcCore(options => options.OutputFormatters.Add(new XmlSerializerOutputFormatter())
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

CustomerDto.cs:

namespace WebApplication
{
    public class CustomerDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在向请求添加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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

它将返回json.对于这个模型你应该添加

public CustomerDto()
{
}
Run Code Online (Sandbox Code Playgroud)

这将再次返回XML.

  • +1表示无参数的构造函数,否则,有人会花几个小时挠头思考到底发生了什么! (4认同)

Saj*_*dan 7

以下解决方案对我来说效果很好。

Startup.cs

services.AddMvc()
       .AddXmlSerializerFormatters()
       .AddXmlDataContractSerializerFormatters();
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)


ars*_*ars 6

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

     //...
}
Run Code Online (Sandbox Code Playgroud)

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

现在它应该适用于xmljson


小智 5

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

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => { options.RespectBrowserAcceptHeader = true; })
        .AddXmlSerializerFormatters()
        .AddXmlDataContractSeria??lizerFormatters();
}
Run Code Online (Sandbox Code Playgroud)

现在您可以设置接受标题:

XML: application/xml

JSON: application/json