ASP.NET Core 中内容类型“application/csp-report”的“415 Unsupported Media Type”

Bri*_*ian 9 c# asp.net-core asp.net-core-3.1

我有一个内容安全策略导致 Chrome 发布报告,但接收报告的操作返回“415 不支持的媒体类型”。我理解这是因为该帖子的 Content-Type 为“application/csp-report”。我如何将其添加为 Core 3.1 中允许的内容类型(它基本上只是 json)。

行动

// https://anthonychu.ca/post/aspnet-core-csp/
[HttpPost][Consumes("application/csp-report")]
public IActionResult Report([FromBody] CspReportRequest request)
{
    return Ok();
}
Run Code Online (Sandbox Code Playgroud)

模型的缩减版本

public class CspReportRequest
{
    [JsonProperty(PropertyName = "csp-report")]
    public CspReport CspReport { get; set; }
}

public class CspReport
{
    [JsonProperty(PropertyName = "document-uri")]
    public string DocumentUri { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Kir*_*kin 8

以下示例显示了如何添加SystemTextJsonInputFormatter对处理其他媒体类型的支持:

services.AddControllers(options =>
{
    var jsonInputFormatter = options.InputFormatters
        .OfType<SystemTextJsonInputFormatter>()
        .Single();

    jsonInputFormatter.SupportedMediaTypes.Add("application/csp-report");
});
Run Code Online (Sandbox Code Playgroud)

这是一个两步过程:

  1. 查询输入格式化程序的配置列表以找到SystemTextJsonInputFormatter.
  2. 添加application/csp-report到其现有的支持的媒体类型的列表(application/jsontext/json,和application/*+json)。

如果您使用的是 Json.NET 而不是System.Text.Json,则方法类似

services.AddControllers(options =>
{
    var jsonInputFormatter = options.InputFormatters
        .OfType<NewtonsoftJsonInputFormatter>()
        .First();

    jsonInputFormatter.SupportedMediaTypes.Add("application/csp-report");
})
Run Code Online (Sandbox Code Playgroud)

有两个小的区别:

  1. 类型是NewtonsoftJsonInputFormatter而不是SystemTextJsonInputFormatter.
  2. 集合中有两个这种类型的实例,因此我们针对第一个实例(有关详细信息,请参阅此答案)。

请参阅ASP.NET Core 文档中的输入格式化程序以了解有关这些内容的更多信息。


Vin*_*ten 8

我想补充一点,接受的解决方案对我不起作用。(.NET Core 3.1)关于 CSP 报告,我有完全相同的用例。当尝试使用 NewtonSoft 并修改 InputFormatterNewtonsoftJsonInputFormatter以接受媒体头类型时application/csp-report,我总是会得到一个异常,说无法找到 inputformatter (有或没有.AddNewtonsoftJson();

我通过执行以下操作成功解决了该问题:

services.AddControllers().AddNewtonsoftJson();
services.AddOptions<MvcOptions>()
      .PostConfigure<IOptions<JsonOptions>, IOptions<MvcNewtonsoftJsonOptions>, ArrayPool<char>, ObjectPoolProvider, ILoggerFactory>(
          (mvcOptions, jsonOpts, newtonJsonOpts, charPool, objectPoolProvider, loggerFactory) =>
          {
              var formatter = mvcOptions.InputFormatters.OfType<NewtonsoftJsonInputFormatter>().First(i => i.SupportedMediaTypes.Contains("application/json"));
              formatter.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/csp-report"));
              mvcOptions.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>();
              mvcOptions.InputFormatters.Add(formatter);
          });
Run Code Online (Sandbox Code Playgroud)

我的模型和控制器操作与问题中发布的相同。

(我的解决方案来自如何配置两个 JSON 序列化器并根据路由选择正确的序列化器