ASP.NET Core中OkObjectResult返回XmlDocument时忽略Accept标头问题
这确实是ASP.NET Core 2.x的预期行为,原因和细节如下:
当你使用OkObjectResult返回数据时,ASP.NET Core会通过内容协商机制来决定用哪种格式化器(JSON/XML等)来序列化你的返回对象。这里的核心问题是:默认的XML格式化器不支持序列化XmlDocument类型,但JSON格式化器支持。
具体拆解原因:
- 内容协商的逻辑:框架会先查看请求的
Accept头,然后遍历已注册的输出格式化器,找到第一个能够处理返回对象类型的格式化器。如果没有找到匹配application/xml且能处理XmlDocument的格式化器,就会回退到使用默认的格式化器(在API模板中默认是JSON格式化器)。 - XML格式化器的限制:ASP.NET Core默认的
XmlSerializerOutputFormatter依赖.NET XmlSerializer,它只能序列化符合特定条件的类型——比如带有[Serializable]特性的POCO类,或者你显式配置了序列化映射的类型。XmlDocument是DOM对象,不属于XmlSerializer默认支持的序列化范畴,所以XML格式化器会直接跳过处理这个对象。 - JSON格式化器的兼容性:默认的
JsonOutputFormatter基于Newtonsoft.Json,它对.NET内置类型的兼容性更广,包括XmlDocument这类DOM对象,所以它会被选中来序列化你的返回值,最终返回JSON格式。
补充你提到的解决思路:
除了你说的用ContentResult手动返回XML内容:
return Content(xmlContent.OuterXml, "application/xml");
还有另一种更符合框架规范的方式:把XmlDocument转换成XDocument(XDocument默认被XML格式化器支持),然后用OkObjectResult返回:
var xDoc = XDocument.Parse("<MyData><StringProperty>foo</StringProperty></MyData>"); return Ok(xDoc);
这样当请求Accept:application/xml时,就会正确返回XML格式的响应了。
内容的提问来源于stack exchange,提问作者Paul Batum
相关产品推荐
相关产品推荐

