问题
In our ASP.NET Core based web application, we want the following: certain requested file types should get custom ContentType's in response. E.g. .map
should map to application/json
. In "full" ASP.NET 4.x and in combination with IIS it was possible to utilize web.config <staticContent>/<mimeMap>
for this and I want to replace this behavior with a custom ASP.NET Core middleware.
So I tried the following (simplified for brevity):
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";
}
}
}
Unfortunately, trying to set context.Response.ContentType
after invoking the rest of the middleware chain yields to the following exception:
System.InvalidOperationException: "Headers are read-only, response has already started."
How can I create a middleware that solves this requirement?
回答1:
Try to use HttpContext.Response.OnStarting
callback. This is the last event that is fired before the headers are sent.
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);
}
回答2:
Using an overload of OnStarting method:
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);
}
来源:https://stackoverflow.com/questions/37918547/middleware-to-set-response-contenttype