.NET Web API如何配置XML格式化器
发布时间 - 2026-02-02 00:00:00 点击率:次.NET 6+ Web API 默认不支持 XML 响应,因移除了 XmlSerializerOutputFormatter,需手动安装 Microsoft.AspNetCore.Mvc.Formatters.Xml 包并注册该格式化器,且模型须满足无参构造、public 属性等要求。
为什么默认不支持 XML 响应
.NET 6+ 的 Web API 模板默认只注册 SystemTextJsonOutputFormatter,完全移除了对 XML 的自动支持。即使你返回 IActionResult 或启用了 [Produces("application/xml")],请求带 Accept: application/xml 也会直接 406 Not Acceptable。
添加 XmlSerializerOutputFormatter 的正确方式
必须显式注册基于 XmlSerializer 的格式化器(XmlDataContractSerializer 已被弃用且不推荐用于 Web API)。注意:.NET 5+ 不再内置 XML 支持包,需先安装 NuGet 包:
dotnet add package Microsoft.AspNetCore.Mvc.Formatters.Xml
然后在 Program.cs 中注册:
builder.Services.AddControllers(options =>
{
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
// 可选:禁用默认的 JSON 格式化器(仅需 XML 时)
// options.OutputFormatters.RemoveType();
});
关键点:
-
XmlSerializerOutputFormatter要求模型类有无参构造函数,且属性必须是 public get/set - 不支持
record类型(会抛InvalidOperationException: Type 'X' cannot be serialized) - 若控制器方法返回
Task,确保实际返回值类型可被XmlSerializer序列化(如Ok(MyModel))
处理 XML 请求(POST/PUT)
仅配置输出格式化器不够——接收 XML 请求体还需注册输入格式化器:
builder.Services.AddControllers(options =>
{
options.InputFormatters.Add(new XmlSerializerInputFormatter(options));
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
此时需确保请求头包含 Content-Type: application/xml,且 XML 结构与模型字段名严格匹配(区分大小写,无命名空间更稳妥)。常见失败原因:
- XML 根节点名 ≠ 模型类名(
XmlRoot特性可覆盖) - 字段名含下划线或驼峰,但 XML 使用短横线(如
)→ 需加[XmlElement("user-name")] - 传了空字符串给非 nullable 引用类型字段 → 反序列化失败
调试 406 或空响应的快速检查项
当 XML 响应不生效时,优先验证以下三点:
- 是否漏装
Microsoft.AspNetCore.Mvc.Formatters.Xml包?没有它,XmlSerializerOutputFormatter类型根本不存在 - 是否在
AddControllers()后才调用Build()?顺序错误会导致注册失效 - 是否误用了
serv(已过时)?.NET 6+ 推荐统一用
ices.AddMvc()
AddControllers()+AddEndpointsApiExplorer() - 是否在
Startup.Configure()中忘了调用app.UseRouting()和app.UseEndpoints()?中间件链中断会导致格式化器不触发
XML 格式化器本身不处理缩进或编码声明,生成的 XML 默认无换行、UTF-8 无 BOM。如果需要美化输出,得自己封装 XmlWriterSettings 并继承 XmlSerializerOutputFormatter —— 这部分容易被低估工作量。
# js
# json
# 编码
# app
# microsoft
# .net
# 为什么
# mvc
# 中间件
# 命名空间
# 封装
# 构造函数
# xml
# 字符串
# 继承
# 值类型
# 引用类型
# public
# Nullable
# bom
# 不支持
# 移除
# 字段名
# 序列化
# 也会
# 已被
# 下划线
# 这部
# 不存在
# 可选
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
微信小程序 input输入框控件详解及实例(多种示例)
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
JS弹性运动实现方法分析
Laravel集合Collection怎么用_Laravel集合常用函数详解
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
制作公司内部网站有哪些,内网如何建网站?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
Laravel如何集成Inertia.js与Vue/React?(安装配置)
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
WordPress 子目录安装中正确处理脚本路径的完整指南
Laravel怎么清理缓存_Laravel optimize clear命令详解
如何确认建站备案号应放置的具体位置?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
Laravel中的Facade(门面)到底是什么原理
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
百度浏览器如何管理插件 百度浏览器插件管理方法
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
Laravel如何使用Eloquent进行子查询
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
php打包exe后无法访问网络共享_共享权限设置方法【教程】
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
html如何与html链接_实现多个HTML页面互相链接【互相】
如何快速使用云服务器搭建个人网站?
Laravel Docker环境搭建教程_Laravel Sail使用指南
如何用搬瓦工VPS快速搭建个人网站?
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】
javascript如何操作浏览器历史记录_怎样实现无刷新导航
图册素材网站设计制作软件,图册的导出方式有几种?
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
Python3.6正式版新特性预览
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
如何快速生成专业多端适配建站电话?
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
企业网站制作这些问题要关注
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
浅谈javascript alert和confirm的美化
如何打造高效商业网站?建站目的决定转化率
详解vue.js组件化开发实践
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?


