I have an ASP.NET Core minimal API where the endpoints all return strings.
As (very) simplified version of what I’m trying to do is add some middleware so that the string value that the endpoint returns will have “Hello” added to it. This is obviously pretty dumb, but captures enough of my problem whilst keeping the question clear.
I have the following middleware class…
public class SayHelloMiddleware(RequestDelegate next) {
public async Task InvokeAsync(HttpContext httpContext) {
Stream originalBody = httpContext.Response.Body;
try {
using MemoryStream memStream = new();
httpContext.Response.Body = memStream;
await next(httpContext);
memStream.Position = 0;
string responseBody = await new StreamReader(memStream).ReadToEndAsync();
Console.WriteLine($"responseBody: {responseBody}");
memStream.Position = 0;
await memStream.CopyToAsync(originalBody);
} finally {
httpContext.Response.Body = originalBody;
}
}
}
…and register it in Program.cs
as follows…
app.UseMiddleware<SayHelloMiddleware>();
The code above works fine, in that I can get the response body (which I Console.WriteLine
for debugging), and the actual response sent out is what the endpoint returned.
I want to modify the response, so started off by creating a new MemoryStream
from the existing response and setting that as the output…
using MemoryStream modifiedBody = new(Encoding.UTF8.GetBytes(responseBody));
await memStream.CopyToAsync(modifiedBody);
This works fine, and produces the same result as above.
However, if I modify this as follows…
using MemoryStream modifiedBody = new(Encoding.UTF8.GetBytes("Hello: " + responseBody));
await memStream.CopyToAsync(modifiedBody);
…then I get an empty response when I call the endpoint. I don’t understand why this is happening, as the response body on its own is a plain string, so I don’t see why adding another string to it should change anything.
Anyone able to explain what I’m doing wrong here?
This is a brand new ASP.NET Core project, targeting .NET8. I used the WASM template, so have two projects, the server one and the client (WASM) one. All of the code here is in the server project.
In case it helps, here is the Program.cs
file…
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
WebApplication app = builder.Build();
if (app.Environment.IsDevelopment()) {
app.UseWebAssemblyDebugging();
} else {
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMiddleware<SayHelloMiddleware>();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(WasmPlayAgain.Client._Imports).Assembly);
app.MapGet("/hi", () =>
$"It's {DateTime.Now.ToLongTimeString()}");
app.Run();