为路由/控制器使用特定的JSON输出格式化程序



我想为不同的路由或控制器使用不同的JSON输出格式化程序。默认和自定义json输出格式化程序

启动.cs

services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
options.OutputFormatters.Add(new CustomJsonMediaFormatter());                
});

CustomJsonMediaFormatter

public class CustomJsonMediaFormatter : TextOutputFormatter
{        
public JsonMediaFormatter()
{            
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/vnd.XYZ+json"));
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
}
protected override bool CanWriteType(Type type)
{
return true;          
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
// my code
}        
}

控制器A

[ApiController]
[Produces("application/vnd.XYZ+json")]
public class AController : BaseController
{

[HttpGet]
public async Task<IActionResult> Get()
{
// return an object
}
}

控制器B

[ApiController]
[Produces("application/json")]
public class BController : BaseController
{

[HttpGet]
public async Task<IActionResult> Get()
{
// return an object
}
}

当我用Postman向a Cotroller发出请求时,它没有使用我的自定义输出格式化程序。它仍然使用默认的JSON输出格式化程序。

它似乎采用了列表中的第一个JSON输出格式化程序。我试图清除输出格式化程序列表并添加我的自定义json格式化程序。然后它总是使用自定义格式化程序。

我想对自定义输出格式化程序做的是:我想从对象中删除一些不允许用户查看的字段,具体取决于配置。但仅适用于某些API控制器,而不是所有控制器。

如果你查看他们的文档,你会发现他们在列表的开头插入了客户格式化程序。https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-5.0#如何配置emvc-to-use-a自定义格式化程序

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.InputFormatters.Insert(0, new VcardInputFormatter());
options.OutputFormatters.Insert(0, new VcardOutputFormatter());
});
}

这让我相信格式化程序的执行顺序确实很重要,并且很可能在检查您的自定义内容接受类型之前执行默认的json。

尝试将DI更新为:

services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
options.OutputFormatters.Insert(0, new CustomJsonMediaFormatter());                
});

我得到了解决方案。重写函数CanWriteResult。从上下文中我们得到内容类型

public override bool CanWriteResult(OutputFormatterCanWriteContext context)
{
return context.ContentType == "application/vnd.XYZ+json";
}

再加上@JohnD关于格式化程序顺序的回答,它的工作非常完美!

services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
options.OutputFormatters.Insert(0, new CustomJsonMediaFormatter());                
});

最新更新