用于设置响应ContentType的中间件

问题描述 投票:15回答:2

在基于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."

我如何创建可以满足此要求的中间件?

c# asp.net-core asp.net-core-1.0 owin-middleware
2个回答
11
投票

尝试使用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);
}

4
投票

使用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);
}
© www.soinside.com 2019 - 2024. All rights reserved.