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

Mic*_*ltu 9 c# asp.net asp.net-web-api

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

同样的问题适用于403s.如果我尝试导航到我的应用程序的根目录,我会再次返回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. 修改DefaultController,如下所示.
  8. 修改WebApiConfig.cs,如下所示.
  9. 运行/调试

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

DefaultController.cs:

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

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!"""),
                };
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑3

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

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

age*_*tpx 0

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

public JsonResult Handle404()
{
   return Json(new { error404 = "NOT FOUND", Message = "Additional Message" });
}
Run Code Online (Sandbox Code Playgroud)

这将产生

var result =
{
  "error404": "NOT FOUND",
  "Message": "Additional Message"
}; 

alert(result.error404);
allert(result.Message);
Run Code Online (Sandbox Code Playgroud)

  • 包罗万象的路由将明确解决 404 问题,但是我的应用程序可能抛出的所有其他异常又如何呢?一个易于重现的示例是当我尝试访问应用程序的根目录时收到的 403。其他可能包括 IIS 配置错误、应用程序配置错误、应用程序崩溃等。我知道我可能无法让 IIS 针对真正致命的错误(例如内存不足)返回 JSON,但我希望 JSON 响应能够解决所有可能的问题。 (3认同)