-
Notifications
You must be signed in to change notification settings - Fork 10.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix IAsyncEnumerable controller methods to allow setting headers #57924
Conversation
Should we do something for minimal APIs? I don't think it's as important as MVC because you cannot
However, you can run into the with a named function which isn't super rare. And at that point, the repro code looks very similar to what you have for an MVC action. var app = WebApplication.Create(args);
app.MapGet("/", Test);
app.Run();
async IAsyncEnumerable<string> Test(HttpContext context)
{
var testValue = await myService.GetHeaderValueAsync();
context.Response.Headers["Test"] = testValue;
await foreach (var item in myService.GetItemsAsync())
{
yield return item;
}
} I agree that we probably don't need to update app.MapGet("/", async (HttpContext context) =>
{
async IAsyncEnumerable<string> Test()
{
var testValue = await myService.GetHeaderValueAsync();
context.Response.Headers["Test"] = testValue;
await foreach (var item in myService.GetItemsAsync())
{
yield return item;
}
}
await context.Response.WriteAsJsonAsync(Test());
}); Instead of just: app.MapGet("/", async (HttpContext context) =>
{
async IAsyncEnumerable<string> Test()
{
await foreach (var item in myService.GetItemsAsync())
{
yield return item;
}
}
var testValue = await myService.GetHeaderValueAsync();
context.Response.Headers["Test"] = testValue;
await context.Response.WriteAsJsonAsync(Test());
}); I suppose with weird enough layering it's possible that someone might try to mutate the response in an |
Pretty sure minimal just calls into |
Fix IAsyncEnumerable controller methods to allow setting headers
Description
When writing Json responses in MVC, we started flushing headers immediately before using
JsonSerializer
in order to avoid some unnecessary buffering in Kestrel when writing starts before headers are flushed. This had the unintended side-effect of makingIAsyncEnumerable<T>
MVC methods no longer able to set headers due to the fact that the whole method becomes theIAsyncEnumerable
and we pass that directly toJsonSerializer
, which means we've already flushed headers by the time the MVC method starts running. Resulting in an exception on the server and a bad response on the client.Fixes #57895
Customer Impact
MVC methods that returned
IAsyncEnumerable<T>
will now fail if they modify response headers.Regression?
Regressed from 8.0
Risk
Small targeted fix. Added test coverage for scenario.
Verification
Packaging changes reviewed?