【问题标题】:Updating the response body in middleware .NET Core在中间件 .NET Core 中更新响应主体
【发布时间】:2022-12-13 08:48:37
【问题描述】:

我的 .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);
}

使用上述代码,StatusCode 已正确设置,但是响应 Body 为空。如何将自定义消息写入正文?

更新1:

添加了await,但这并不能解决问题。感谢@Jonesopolis 提到这一点。

更新 2

所以我在 Swagger 中测试响应(我也在查看开发人员的网络选项卡)。但是,当我在 Postman 中进行测试时,我得到了预期的响应主体。

所以真正的问题是为什么响应主体没有出现在 Swagger/network 选项卡中?

谢谢!

【问题讨论】:

标签: c# .net-core asp.net-core-middleware


【解决方案1】:

让我直截了当。 我不认为 Swagger 是这里的问题。 如何准确指定内容类型是什么,更重要的是,让响应完成它的工作。

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

【讨论】:

    【解决方案2】:

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

    更改您的代码:

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

    【讨论】:

      【解决方案3】:

      没有必要在第一个块中使用 return 关键字。 你可以使用 else 块来调用下一个中间件。 有用

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

      【讨论】:

      • 这与我最初在问题中提出的有何不同?
      • 那是一样的,只是我使用了扩展方法
      • 以及这将如何解决问题?
      • 仅使用 await 和 else 阻止另一个条件
      猜你喜欢
      • 2021-10-08
      • 2022-11-13
      • 2018-03-31
      • 2017-11-23
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多