如何在 WebAPI 中返回 404 和 403 的 json

本文关键字:json 返回 WebAPI | 更新日期: 2023-09-27 18:35:20

我有一个相当简单的Web API应用程序,目前有一个路由设置。 如果用户尝试访问任何其他路由,他们会得到 404,但 404 的正文是 HTML 而不是 JSON(这是他们的接受标头所要求的)。 让 IIS 使用 JSON 错误响应而不是网页来响应不存在的路由请求的最简单方法(添加到我的项目中的代码/配置最少)是什么?

同样的问题也适用于403。 如果我尝试导航到应用程序的根目录,我会再次返回 403 作为网页。 我希望这是 404,但更大的问题是我如何使来自应用程序的所有响应都是 JSON,而不仅仅是有效路由上的响应? 我之所以提到 403,是因为我正在寻找一种更广泛的解决方案,而不仅仅是设置一条包罗万象的路由,因为我认为这对我处理 403 或控制器操作之外发生的任何其他随机异常都没有帮助。

最好是,我希望我的应用程序尊重请求上的接受标头。 但是,由于我的 API 现在只支持 JSON,我愿意(暂时)接受它总是使用 JSON 响应。

我正在使用WebAPI 2.2和.NET 4.5.2。

编辑

这不是格式化程序问题。 格式化程序正确应用于成功的消息,遵循请求中的接受标头。 这特别是未处理的路由和 Web 服务器错误(例如尝试访问 Web 根目录时禁止)的问题。

编辑 2

重现步骤:

  1. 打开 Visual Studio 2013 Update 4
  2. 新项目
  3. 选择 .NET Framework 4.5.2
  4. 选择> Visual C#> Web> ASP.NET Web 应用程序的模板
  5. 选择"空",取消选中所有文件夹和核心引用。
  6. 右键单击项目>将>新的基架项添加到 Web API 2 控制器> - 空
  7. 修改默认控制器,如下所示。
  8. 修改 WebApiConfig.cs如下所示。
  9. 运行/调试

我期望的是,当我导航到http://localhost:<port>/api/do_stuff时,我会看到 XML 或 JSON 中的Success!,具体取决于接受标头(我这样做),当我导航到任何其他页面时,我应该看到Failure!(我没有)。 相反,当我导航到任何其他页面时,我看到 IIS 的 404 响应。

默认控制器.cs:

[RoutePrefix("api")]
public class DefaultController : ApiController
{
    [HttpGet]
    [Route("do_stuff")]
    public String DoStuff()
    {
        return "Success!";
    }
}

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Filters.Add(new CustomExceptionFilter());
    }
    private class CustomExceptionFilter : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                actionExecutedContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.NotFound)
                {
                    Content = new StringContent(@"""Failure!"""),
                };
            }
        }
    }
}

编辑 3

我还尝试添加全局异常处理程序和异常记录器,如下所示:http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling

在上面的例子中,当我尝试导航到无效路由或导航到站点根目录时,两者都没有调用。

如何在 WebAPI 中返回 404 和 403 的 json

若要将 IIS 配置为对不存在的路由和其他服务器错误使用 JSON 错误响应进行响应,可以使用 web.config 文件中的自定义错误功能。以下是您可以执行的操作:

在 Visual Studio 中打开您的项目。在项目的根目录中找到 web.config 文件。添加或修改部分,如下所示:

 <system.web>
   <customErrors mode="On" defaultRedirect="~/error" redirectMode="ResponseRewrite">
   <error statusCode="404" redirect="~/error/notfound" />
   <error statusCode="403" redirect="~/error/forbidden" />
 </customErrors>
</system.web>
<system.webServer>
 <httpErrors errorMode="Custom">
  <remove statusCode="404" subStatusCode="-1" />
  <remove statusCode="403" subStatusCode="-1" />
  <error statusCode="404" path="~/error/notfound" responseMode="ExecuteURL"/>
  <error statusCode="403" path="~/error/forbidden" responseMode="ExecuteURL"/>
 </httpErrors>
</system.webServer>

在项目的根目录中创建一个名为"错误"的新文件夹。在"错误"文件夹中,创建两个新文件:"NotFound.cshtml"和"Forbidden.cshtml"(如果您使用的是 Razor 页面.cs则为 .cshtml),其中包含以下内容:NotFound.cshtml:

@{
   Response.StatusCode = 404;
   Layout = null;
}
{"error": "Not found"}

Forbidden.cshtml:

@{
   Response.StatusCode = 403;
   Layout = null;
}
{"error": "Forbidden"}

这些文件将返回具有相应状态代码的 JSON 错误响应。

现在,当用户尝试访问不存在的路由时,他们将收到 JSON 错误响应,而不是默认的 404 HTML 页面。同样,在访问应用程序的根目录时,403 响应将以 JSON 形式返回。

确保根据需要调整错误消息和格式。

从计划的 catch-all-route 调用下面的函数以返回如下所示的 jsonResult 操作

public JsonResult Handle404()
{
   return Json(new { error404 = "NOT FOUND", Message = "Additional Message" });
}

这将产生

var result =
{
  "error404": "NOT FOUND",
  "Message": "Additional Message"
}; 
alert(result.error404);
allert(result.Message);

调用 httpget 以获取响应 404 未找到 使用这个

public JsonResult DoSomething() {
        try
        {
            var result = getData();
            return Json(result, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            return Json(HttpNotFound());
        }
    }