为啥我的 ASP.Net Core Web API 控制器不返回 XML?
Posted
技术标签:
【中文标题】为啥我的 ASP.Net Core Web API 控制器不返回 XML?【英文标题】:Why won't my ASP.Net Core Web API Controller return XML?为什么我的 ASP.Net Core Web API 控制器不返回 XML? 【发布时间】:2016-07-11 21:16:59 【问题描述】:我有以下简单的 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>
在 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;
我已经使用了几个小时了,但我只是不明白为什么它不起作用。我试过了:
使action方法同步和异步
直接返回数据,并设置返回类型为IEnumerable<CustomerDto>
将集合转换为数组而不是列表
返回IActionResult
返回单个项目,而不是集合
我已通过在调试器中检查 Accept 标头来验证它是否显示在请求中。
大量“使用 Bing 搜索”并阅读各种博客
从模板创建一个新的 WebAPI 项目,看看那里是否有任何灵感(不是真的)。
我希望它很简单,但我看不到它......
【问题讨论】:
你能证明你在 Startup.cs 中注册了你的 Xml 格式化程序吗? 你配置过格式化程序吗? 这当然是问题所在。上次我使用了默认启用的 WebAPI。我忘记了 ASP.Net 5 中新的轻量级现收现付方法!不过,扩展方法也不是很容易被发现。我必须知道安装另一个 NuGet 包,然后点到 AddMvc() 调用中。 【参考方案1】:Xml 格式化程序是单独包的一部分:Microsoft.AspNetCore.Mvc.Formatters.Xml
添加上面的包并更新你的startup.cs,如下所示:
services
.AddMvc()
.AddXmlDataContractSerializerFormatters();
或
services
.AddMvc()
.AddXmlSerializerFormatters();
【讨论】:
啊...我想知道它是否可能是这样的。遗憾的是文档有点未完成。 MVC5 中不是默认启用了 XML 格式化程序吗? 是的,它在 MVC5 中,但在 ASP.NET 5 中很早就改变了 @TimLong:您可能必须在 MSDN 中查找该信息。 最新版的asp.net core好像没有这些方法! 在 mvc 1.1 中我需要:services.AddMvc(options => options.RespectBrowserAcceptHeader = true;).AddXmlSerializerFormatters().AddXmlDataContractSerializerFormatters();
否则它总是会给我 json【参考方案2】:
对于 Asp.Net Core 2.x,您基本上需要这 3 个东西才能返回 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。
【讨论】:
+1 用于无参数构造函数点,否则有人会花几个小时挠头想知道发生了什么! 这不是基于提供的Accept
标头吗.. 我很确定 API 就是这样工作的..
关于无参数构造函数:返回匿名对象时也是如此。当你这样做时,它总是会返回 JSON!【参考方案3】:
对于 MVC 1.1,您需要添加 Package Microsoft.AspNetCore.Mvc.Formatters.Xml
并编辑您的 Startup.cs:
public void ConfigureServices(IServiceCollection services)
services.AddMvc(options => options.RespectBrowserAcceptHeader = true; )
.AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters();
现在您可以设置 Accept Header:
XML:application/xml
JSON:application/json
【讨论】:
【参考方案4】:对于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
【讨论】:
【参考方案5】:以下解决方案对我很有效。
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】:对于 .net core 3.x,你可以像下面这样使用
services.AddControllers(options=>
options.OutputFormatters.RemoveType(typeof(SystemTextJsonOutputFormatter));
options.InputFormatters.RemoveType(typeof(SystemTextJsonInputFormatter));
options.ReturnHttpNotAcceptable = true;
).AddXmlSerializerFormatters();
【讨论】:
【参考方案7】:对于 Core 2.x 版本,您唯一需要做的就是在 Startup.cs 文件的 ConfigureServie 方法 中包含以下代码。 p>
public void ConfigureServices(IServiceCollection services)
services.AddMvc()
.AddMvcOptions(o => o.OutputFormatters.Add(
new XmlDataContractSerializerOutputFormatter()));
您需要参考 Microsoft.AspNetCore.Mvc.Formatters。
【讨论】:
【参考方案8】:对于 Core 2.x 版本,您必须做两件事。首先,您需要在 Startup.cs 文件的 ConfigureServices 方法中添加以下代码。
services.AddMvc()
.AddMvcOptions(o => o.OutputFormatters.Add(
new XmlDataContractSerializerOutputFormatter())
);
然后在 Postman 上将 Accept "application/xml" 标头添加到请求中,如下所示。然后会返回 XML 格式的结果。
【讨论】:
以上是关于为啥我的 ASP.Net Core Web API 控制器不返回 XML?的主要内容,如果未能解决你的问题,请参考以下文章
我正在将我的 asp.net web api 迁移到 asp.net core。 Cors 迁移
ASP.NET Core Web API DELETE 调用返回 405
为啥我的 Asp.Net Core 日志中出现“不支持 POST 请求”?