I created a new Asp.Net WebApi project just to experiment, and I added a new inline middleware as in the documentation. The application starts, but when calling the action from Swagger I get a result error. Debugging I see that the middleware code is called, the action code too, but then I get this exception: System.InvalidOperationException: Headers are read-only, response has already started. I tried to move the inline middleware in other places, but always with the same result (or the Swagger page not showing at all in some cases). Why isn't this working? Who is trying to write to headers after the response? And how am I supposed to add an inline middleware with such a project?
Here is the Program code:
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.Use(async (context, next) =>
{
// Do work that can write to the Response.
await context.Response.WriteAsync("Hello from middleware.");
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
app.MapControllers();
app.Run();
}
UPDATE: I tried the same starting with Asp.Net core Empty template getting the same result! Before .Net6 it was working. The exception is raised by the await context.Response.WriteAsync before the call to next. I always get the System.InvalidOperationException: Headers are read-only, response has already started. Here is the code in this case:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) =>
{
// Do work that can write to the Response.
await context.Response.WriteAsync("Hello from middleware.");
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
app.MapGet("/", () => "Hello World!");
app.Run();
Why isn't this working?
Just as the error indicates:
response has already started.WriteAsync
method has already write the response ,you should shortcut the middleware once the response has started.
Also,You could check if the response has started with:
var started = context.Response.HasStarted;
Who is trying to write to headers after the response?
You would write response again in controller,and framework would add some basic response header when it return response in controller,you could check this issue related
If you just want to add some content to response,you may configure callback with context.Response.OnStarting
as below
app.Use(async (context, next) =>
{
// Do work that can write to the Response.
//await context.Response.WriteAsync("Hello from middleware.");
context.Response.OnStarting(async () =>
{
await context.Response.WriteAsync("Hello from middleware.");
});
var started = context.Response.HasStarted;
await next(context);
// Do logging or other work that doesn't write to the Response.
});
Result: