6

I need to throw HttpException during AjaxRequest in Controller and CustomFilterAttribute

When I throw Exception in Controller with 403 error

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

In client script I always get the result code - 500

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

How can I throw HttpException in my FilterAttribute and get this code in client page. I try do this, but I get 200 status code:

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

When I try throw Exception in FilterAttribute I get 500 Status Code again

Kronos
  • 482
  • 4
  • 19

1 Answers1

6

First things first HttpStatusCode.Unauthorized = 401, not 403 status code. There is an important distinction between those 2 codes.

When you set the status code to 401 some nasty things happen: you automatically get redirected to the Login page by the ASP.NET Forms authentication module => the login page is served with status code = 200. Phil Haack addressed this issue in the following blog post.

As far as throw new HttpException((int)HttpStatusCode.Forbidden, "Forbidden"); is concerned in your controller action, well, you throw an exception that is of type HttpException and whose StatusCode is set to 401 but other than that there is absolutely nothing that will catch this exception and set the corresponding response status code. So the exception bubbles up and since you don't presumably have a global exception handler it is translated as a 500 error page by the server.

Here's an example of a global exception handler that you might find useful.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thx. I don't want redirect while `HttpStatusCode.Unauthorized` error, because in client in this case I get the login page and 200 ( success ) result. I want translate my custom codes in error ajax function-callback, but web server always notify me as 500 status code. In controller I can catch 2 exceptions ( access, and internal error ) and in client code I need translate it. – Kronos Dec 01 '11 at 08:43