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

时间:2014-12-27 09:32:42

标签: 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#>网络> ASP.NET Web应用程序
  5. 选择“清空”,保留所有文件夹和核心参考未选中
  6. 右键单击项目>添加>新的脚手架项目> Web API 2控制器 - 清空
  7. 修改DefaultController,如下所示。
  8. 修改WebApiConfig.cs,如下所示。
  9. 运行/调试
  10. 我希望当我导航到http://localhost:<port>/api/do_stuff时,我会在XML或JSON中看到Success!,具体取决于接受标头(我这样做),当我导航到任何其他页面时,我应该看到{ {1}}(我没有)。相反,当我导航到任何其他页面时,我会看到IIS的404响应。

    DefaultController.cs:

    Failure!

    WebApiConfig.cs:

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

    编辑3

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

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

调用httpget以获取响应404 notfound使用此

public JsonResult DoSomething() {
        try
        {

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

    }