如何在ASP.NET Core 2控制器操作中获取协商后的Content-Type?
在ASP.NET Core 2中获取内容协商后的Content-Type
嘿,这个问题我刚好踩过坑!在ASP.NET Core 2里确实有对应的方式拿到内容协商后的Content-Type,和旧版Web API的ContentNegotiationResult思路相通,但实现细节有所不同,我给你两种常用的方案:
方案一:手动触发内容协商(推荐在控制器内做逻辑判断时用)
如果你需要在返回结果前,就获取到协商后的ContentType来做业务逻辑,可以手动调用ASP.NET Core的内容协商机制,步骤如下:
- 首先在控制器的构造函数中注入
IOutputFormatterSelector和IHttpResponseStreamWriterFactory这两个服务; - 在你的动作方法里,创建
OutputFormatterWriteContext对象,传入当前的HttpContext、数据类型和返回数据; - 调用
SelectFormatter方法获取选中的格式化器,同时就能拿到协商后的ContentType了。
示例代码如下:
private readonly IOutputFormatterSelector _formatterSelector; private readonly IHttpResponseStreamWriterFactory _writerFactory; public YourController(IOutputFormatterSelector formatterSelector, IHttpResponseStreamWriterFactory writerFactory) { _formatterSelector = formatterSelector; _writerFactory = writerFactory; } public IActionResult GetData() { var yourData = new { Id = 1, Name = "Test Data" }; var objectResult = new ObjectResult(yourData); // 创建内容协商上下文 var writeContext = new OutputFormatterWriteContext( HttpContext, _writerFactory.CreateWriter, yourData.GetType(), yourData ); // 执行内容协商,选中合适的格式化器 var selectedFormatter = _formatterSelector.SelectFormatter(writeContext, objectResult.Formatters, objectResult.ContentTypes); if (selectedFormatter != null) { // 这里就是协商后的Content-Type string negotiatedContentType = writeContext.ContentType.ToString(); // 你可以基于这个值做任何逻辑,比如记录日志、调整返回数据等 } return objectResult; }
方案二:直接获取响应已设置的ContentType
如果你不需要在返回结果前做处理,只是想拿到最终响应的ContentType,可以直接访问HttpContext.Response.ContentType。不过要注意,这个值是在ASP.NET Core完成内容协商、准备响应时才会被设置的,所以如果你在动作方法刚开头就访问,可能拿到的是默认值,建议在动作过滤器(Action Filter)里或者返回结果后访问。
举个过滤器里的例子:
public class LogContentTypeFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { // 这里还没完成协商,ContentType可能是空或者默认值 } public void OnActionExecuted(ActionExecutedContext context) { // 这里内容协商已完成,可以拿到最终的ContentType string contentType = context.HttpContext.Response.ContentType; // 比如记录日志 Console.WriteLine($"Negotiated Content-Type: {contentType}"); } }
对比旧版ASP.NET Web API的ContentNegotiationResult,这里的selectedFormatter对应选中的格式化程序,writeContext.ContentType就是协商后的ContentType,功能上是完全对应的。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

