18

在我们基于 ASP.NET Core 的 Web 应用程序中,我们需要以下内容:某些请求的文件类型应获得自定义 ContentType 的响应。例如.map应该映射到application/json. 在“完整”的 ASP.NET 4.x 中并结合 IIS,可以利用 web.config<staticContent>/<mimeMap>来实现这一点,我想用自定义的 ASP.NET Core 中间件替换这种行为。

所以我尝试了以下方法(为简洁起见):

public async Task Invoke(HttpContext context)
{
    await nextMiddleware.Invoke(context);

    if (context.Response.StatusCode == (int)HttpStatusCode.OK)
    {
        if (context.Request.Path.Value.EndsWith(".map"))
        {
            context.Response.ContentType = "application/json";
        }
    }
}

context.Response.ContentType不幸的是,在调用中间件链的其余部分后尝试设置会导致以下异常:

System.InvalidOperationException: "Headers are read-only, response has already started."

如何创建解决此要求的中间件?

4

2 回答 2

16

尝试使用HttpContext.Response.OnStarting回调。这是在发送标头之前触发的最后一个事件。

public async Task Invoke(HttpContext context)
{
    context.Response.OnStarting((state) =>
    {
        if (context.Response.StatusCode == (int)HttpStatusCode.OK)
        {
           if (context.Request.Path.Value.EndsWith(".map"))
           {
             context.Response.ContentType = "application/json";
           }
        }          
        return Task.FromResult(0);
    }, null);

    await nextMiddleware.Invoke(context);
}
于 2016-06-20T10:20:34.797 回答
6

使用 OnStarting 方法的重载:

public async Task Invoke(HttpContext context)
{
    context.Response.OnStarting(() =>
    {
        if (context.Response.StatusCode == (int) HttpStatusCode.OK &&
            context.Request.Path.Value.EndsWith(".map"))
        {
            context.Response.ContentType = "application/json";
        }

        return Task.CompletedTask;
    });

    await nextMiddleware.Invoke(context);
}
于 2016-08-11T12:27:52.267 回答