【问题标题】:How to use Middleware to overwrite response body on 405 - MethodNotAllowed如何使用中间件覆盖 405 上的响应正文 - MethodNotAllowed
【发布时间】:2020-09-29 22:55:07
【问题描述】:

我正在将一个 API 从 .NET 移植到 .NET Core。对于任务,每个响应都需要相同。 如果我在仅“GET”端点上尝试“PUT”请求,旧 API 在 Postman 中返回以下状态码 405:

{
"Message": "The requested resource does not support http method 'PUT'."}

.NET Core 默认返回 405 的空正文。

我的问题是如何在 .NET CORE 中模拟第一个示例的响应正文。

我目前的尝试使我创建了一个在app.UseRouting(); 之前添加的中间件。 中间件如下所示: public class MethodNotAllowedMiddleware { 私有 RequestDelegate _next;

    public MethodNotAllowedMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await _next(context);

        if(context.Response.StatusCode == (int)HttpStatusCode.MethodNotAllowed)
        {
            await context.Response.WriteAsync("The requested resource does not support http method 'PUT'.");//This will NOT be hardcoded string
        }
    }
}

但是响应正文是纯字符串,而不是 JSON 格式。 如何使用适当的类而不是硬编码字符串来构建响应?我认为这是一个非常 hacky 的解决方案,应该有一种更优雅的方式来解决我所缺少的问题。

【问题讨论】:

    标签: api asp.net-core asp.net-core-webapi


    【解决方案1】:

    我在正确的轨道上,我错过了为响应正文设置响应状态码、内容类型和序列化 JSON。

    调整后的中间件主体如下: 等待_next(上下文);

            if (context.Response.StatusCode == (int)HttpStatusCode.MethodNotAllowed && context.Response.HasStarted == false)
            {
                //Assign the error message
                MiddlewareErrorMessage msg = new MiddlewareErrorMessage($"The requested resource does not support http method '{context.Request.Method}'.");
                // Set the status code
                context.Response.StatusCode = 405;
                // Set the content type
                context.Response.ContentType = "application/json; charset=utf-8";
                string jsonString = JsonConvert.SerializeObject(msg);
                await context.Response.WriteAsync(jsonString, Encoding.UTF8);
            }
    

    “MiddlewareErrorMessage”只是包含我要返回的错误的结构

    【讨论】:

      【解决方案2】:

      在此处查看自定义错误处理:https://joonasw.net/view/custom-error-pages

      您可以重新路由到新路径并使用 MVC 创建您想要的任何对象/页面:

      app.Use(async (ctx, next) =>
      {
          await next();
      
          if (ctx.Response.StatusCode == 405 && !ctx.Response.HasStarted)
          {
              //Re-execute the request so the user gets the error page
              string originalPath = ctx.Request.Path.Value;
              ctx.Items["originalPath"] = originalPath;
              ctx.Request.Path = "/Home/Error405";
              await next();
          }
      });
      

      还有你的控制器代码:

      public class HomeController : Controller
      {
          [AllowAnonymous]
          public IActionResult Error405()
          {
              return new ObjectResult(new Response { 
                 Message = "The requested resource does not support http method 'PUT'."
              }) {
                  StatusCode = 405
              };
          }
      
          public class Response
          {
              public string Message { get; set; }
          }
      }
      
      • 确保包裹AllowAnonymous 以禁用授权流程

      【讨论】:

        猜你喜欢
        • 2019-09-12
        • 2020-11-06
        • 2019-05-09
        • 2018-04-02
        • 1970-01-01
        • 2017-05-22
        • 2013-03-04
        • 2022-07-10
        • 2010-10-17
        相关资源
        最近更新 更多