简体   繁体   English

更新中间件 .NET Core 中的响应体

[英]Updating the response body in middleware .NET Core

I have a custom middleware in my .NET Core 3.1 application, and trying to set the response StatusCode and Body like this:我的 .NET Core 3.1 应用程序中有一个自定义中间件,并尝试像这样设置响应 StatusCode 和 Body:

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.使用上面的代码,StatusCode 设置正确,但是响应正文为空。 How can I write my custom message to the Body?如何将自定义消息写入正文?

Update1:更新1:

Added await , but this won't solve the issue.添加了await ,但这不会解决问题。 Thanks @Jonesopolis for mentioning that.感谢@Jonesopolis 提到这一点。

Update 2更新 2

So I was testing the response in Swagger (I was also looking at the developer's Network tab).所以我正在测试 Swagger 中的响应(我也在查看开发人员的网络选项卡)。 However, when I tested in Postman, I was getting the expected response body.但是,当我在 Postman 中进行测试时,我得到了预期的响应体。

So the question really is why the response body wasn't showing up in Swagger/network tab?所以问题真的是为什么响应正文没有出现在 Swagger/network 选项卡中?

Thanks!谢谢!

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. SwaggerUI在请求中设置了一个 accept: text/plain标头,因此 ASP.NET Core 忽略了任何未设置为此类型的内容。

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);
        
}

It is not necessary to use return keyword in your first block.不必在第一个块中使用 return 关键字。 you can use else block to call next middleware.您可以使用 else 块来调用下一个中间件。 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>();
        }
    }
   

Let me get it straight.让我直截了当。 I don't think Swagger is the issue here.我不认为 Swagger 是这里的问题。 How about specify exactly the content type, 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM