如何在Ajax(Post)请求中抛出自定义的HTTP状态码

6

我需要在ControllerCustomFilterAttribute中的AjaxRequest事件中抛出HttpException

当我在Controller中抛出带有403错误的Exception时。

[HttpPost]
[CustomAuthorize]
public ActionResult AjaxSelectBinding()
{
     // 403 Error code
     throw new HttpException((int)HttpStatusCode.Forbidden, "Forbidden");
}

在客户端脚本中,我总是得到结果代码 - 500

 $.ajax({
            type: 'POST',
            url: '/Groups/AjaxSelectBinding',
            success: function(data) {
            },
            error: function (xhr, ajaxOptions, thrownError) {
                 // HERE I GET ALWAYS 500 ERROR CODE
            }
        });

我如何在我的FilterAttribute中抛出HttpException并在客户端页面获取此代码。我尝试这样做,但我得到了200状态码:

public class CustomAuthorize : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        SharedControllerBase ctrl = (SharedControllerBase)filterContext.Controller;

        if (!ctrl.User.Identity.IsAuthenticated &&
             filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        }
    }

当我在FilterAttribute中尝试抛出Exception时,我再次获得500状态码。

1个回答

6

首先要明确的是 HttpStatusCode.Unauthorized = 401,而不是403状态码。这两个状态码之间有一个重要的区别。

当您将状态码设置为401时,会发生一些讨厌的事情:ASP.NET Forms身份验证模块会自动将您重定向到登录页面 => 登录页面的状态代码为200。Phil Haack在以下博客文章中解决了这个问题。

至于您控制器操作中的throw new HttpException((int)HttpStatusCode.Forbidden, "Forbidden");,那么,您抛出了一个类型为HttpException且其StatusCode设置为401的异常,但除此之外,没有任何东西可以捕获此异常并设置相应的响应状态码。因此,该异常会上升,并且由于您可能没有全局异常处理程序,服务器将其转换为500错误页面。

这里有一个全局异常处理程序的示例,可能对您有用。

谢谢。我不想在出现 HttpStatusCode.Unauthorized 错误时进行重定向,因为在客户端中,这种情况下我会得到登录页面和 200(成功)的结果。我想在错误的 ajax 函数回调中翻译我的自定义代码,但是 Web 服务器总是通知我 500 状态码。在控制器中,我可以捕获 2 个异常(访问和内部错误),在客户端代码中我需要将其翻译。 - Kronos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接