这是一个简单的例子: 中间件:
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() });
}
}
注册:
app.UseMiddleware<AuthorizationMiddleware>();
app.UseMiddleware<RequestHeaderMiddleware>();
app.UseMiddleware<ProcessingTimeMiddleware>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
为什么这段代码await context.Response.WriteAsync("test");
没有在课堂上调用?它只有在我注册MVC时才有用。 MVC如何阻止继续执行方法?我错过了c#中的内容吗?
答案 0 :(得分:3)
如果某些中间件已经开始写入响应,则您无法执行编辑响应标头等操作。这就是为什么docs建议不要在其他中间件运行之后操纵头文件(例如,在调用_next.Invoke()之后,在堆栈的路上&#34; out&#34 ;.
您应该找到一种方法来记录您想要的信息并不直接写入响应。一种方法是简单地将其记录并存储在服务器(缓存,数据库)上,并在单独的请求中查看它。
当您添加MVC时,它将发送标头并开始发送响应正文。这就是为什么在MVC之后运行的代码无法再写入响应的原因 - 它已被发送。
答案 1 :(得分:0)
尝试以下代码:
context.Response.OnStarting(() =>
{
context.Response.Headers.Add("X-Transfer-Success", "true");
});
// await context.Response.WriteAsync("test");
await _next(context);