Добавление заголовков ответов к промежуточному средству ASP.NET Core
Я хочу добавить промежуточное программное обеспечение для обработки в свой ASP.NET Core WebApi, как это
public class ProcessingTimeMiddleware
{
private readonly RequestDelegate _next;
public ProcessingTimeMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var watch = new Stopwatch();
watch.Start();
await _next(context);
context.Response.Headers.Add("X-Processing-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() });
}
}
Но это делает исключение, говорящее
System.InvalidOperationException: Headers are readonly, reponse has already started.
Как добавить заголовки в ответ?
Ответы
Ответ 1
Ничего, код здесь
public async Task Invoke(HttpContext context)
{
var watch = new Stopwatch();
watch.Start();
//To add Headers AFTER everything you need to do this
context.Response.OnStarting(state => {
var httpContext = (HttpContext)state;
httpContext.Response.Headers.Add("X-Response-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() });
return Task.FromResult(0);
}, context);
await _next(context);
}
Ответ 2
Использование перегрузки метода OnStarting:
public async Task Invoke(HttpContext context)
{
var watch = new Stopwatch();
context.Response.OnStarting(() =>
{
watch.Stop();
context
.Response
.Headers
.Add("X-Processing-Time-Milliseconds",
new[] { watch.ElapsedMilliseconds.ToString() });
return Task.CompletedTask;
});
watch.Start();
await _next(context);
}
Ответ 3
В ваших примерах уже отправлены заголовки, когда выполнение достигает context.Response.Headers.Add(...).
Вы можете попробовать:
public async Task Invoke(HttpContext context)
{
var watch = new Stopwatch();
context.Response.OnSendingHeaders(x =>
{
watch.Stop();
context.Response.Headers.Add("X-Processing-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() });
}, null);
watch.Start();
await _next(context);
watch.Stop();
}
Ответ 4
В качестве альтернативы вы также можете добавить промежуточное программное обеспечение непосредственно в метод Startup.cs Configure.
app.Use(
next =>
{
return async context =>
{
var stopWatch = new Stopwatch();
stopWatch.Start();
context.Response.OnStarting(
() =>
{
stopWatch.Stop();
context.Response.Headers.Add("X-ResponseTime-Ms", stopWatch.ElapsedMilliseconds.ToString());
return Task.CompletedTask;
});
await next(context);
};
});
app.UseMvc();