Reputation: 2939
Here is a simple example: Middlewares:
public class AuthorizationMiddleware
{
private readonly RequestDelegate _next;
public AuthorizationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Headers.Keys.Contains("X-Not-Authorized"))
{
context.Response.StatusCode = 401;
return;
}
await _next.Invoke(context);
}
}
public class RequestHeaderMiddleware
{
private readonly RequestDelegate _next;
public RequestHeaderMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Headers.Keys.Contains("X-Cancel-Request"))
{
context.Response.StatusCode = 500;
return;
}
await _next.Invoke(context);
// not calling
context.Response.Headers.Add("X-Transfer-Success", "true");
await context.Response.WriteAsync("test");
}
}
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() });
}
}
registration:
app.UseMiddleware<AuthorizationMiddleware>();
app.UseMiddleware<RequestHeaderMiddleware>();
app.UseMiddleware<ProcessingTimeMiddleware>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Why does this code await context.Response.WriteAsync("test");
not calling in the class? And it doesn't work only if I register MVC. How does MVC prevent continue method execution? Am I missed something in c# ?
Upvotes: 0
Views: 2719
Reputation: 1
Try the code below:
context.Response.OnStarting(() =>
{
context.Response.Headers.Add("X-Transfer-Success", "true");
});
// await context.Response.WriteAsync("test");
await _next(context);
Upvotes: 0
Reputation: 8922
If some middleware has already begun writing to the response, then you can't do things like editing the response headers. This is why the docs recommend against manipulating the headers after other middleware has run (e.g. on the way "out" of the stack, after calling _next.Invoke().
You should find a way to log the information you want that doesn't involve directly writing to the response. One approach is to simply log and store it on the server (cache, database) and view it in a separate request.
When you add MVC, it is going to send headers and start sending the body of the response as well. This is why your code that runs after MVC can no longer write to the response - it's been sent.
Upvotes: 4