Reputation: 1150
I have a custom middleware in my .NET Core 3.1 application, and trying to set the response StatusCode and Body like this:
public async Task Invoke(HttpContext context)
{
if ( <some condition on context.Request> )
{
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
await context.Response.WriteAsync("my custom message");
// Bad request, do not call next middleware.
return;
}
// Call next middleware.
await _requestDelegate(context);
}
With the above code, the StatusCode is correctly set, however, the response Body is empty. How can I write my custom message to the Body?
Update1:
Added await
, but this won't solve the issue. Thanks @Jonesopolis for mentioning that.
Update 2
So I was testing the response in Swagger (I was also looking at the developer's Network tab). However, when I tested in Postman, I was getting the expected response body.
So the question really is why the response body wasn't showing up in Swagger/network tab?
Thanks!
Upvotes: 10
Views: 20673
Reputation: 31
Let me get it straight. I don't think Swagger is the issue here. How about specify exactly what the content type is, and more importantly, let response complete its work.
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
//Unauthorized
context.Response.Headers.Add("Content-Type", "application/json");
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
{
Msg = msg,
LoginPath = _options.LoginPath.Value,
}));
await context.Response.CompleteAsync();
}
Upvotes: 3
Reputation: 36565
SwaggerUI
was setting an accept: text/plain
header with the request so ASP.NET Core was ignoring any content that wasn't set as this type.
Change your code:
public async Task Invoke(HttpContext context)
{
if (xxxx)
{
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
context.Response.ContentType = "text/plain"; //add this line.....
await context.Response.WriteAsync("my custom message");
return;
}
await _requestDelegate(context);
}
Upvotes: 5
Reputation: 460
It is not necessary to use return keyword in your first block. you can use else block to call next middleware. It works
public class CustomMiddleware
{
private readonly RequestDelegate requestDelegate;
public CustomMiddleware(RequestDelegate requestDelegate)
{
this.requestDelegate = requestDelegate;
}
public async Task Invoke(HttpContext httpContext)
{
if(httpContext.Request.Path.Value=="/Custom")
{
httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
await httpContext.Response.WriteAsync("my custom message");
return;
}
else
{
await requestDelegate(httpContext);
}
}
}
public static class Middlewares
{
public static void UseMyCustomMiddleware(this IApplicationBuilder applicationBuilder)
{
applicationBuilder.UseMiddleware<CustomMiddleware>();
}
}
Upvotes: 0