Sailing Judo
Sailing Judo

Reputation: 11243

Is there a way in ASP.NET MVC to handle different Response.StatusCode values?

By default, the MVC Authorize attribute sets the HttpContext.Response.StatusCode = 401 when a user is not authorized and the section in the web.config routes to the loginUrl property.

I want to do something similar with other response codes. For example, I have an attribute called ActiveAccount which verifies the user's account is currently active and then allows them access to the controller. If they are not active I want to route them to a specific controller and view (to update their account).

I'd like to copy the Authorize attributes way of handling this and set the StatusCode to something like 410 (warning: preceding number pulled out of thin air) and have the user routed to a location defined in the web.config file.

What can I do to implement this behavior? Or is there a simpler method?

Edit: Results

I ended up avoiding the StatusCode and just performing a redirection from within the attribute as this was much simpler. Here is my code in a nutshell:

// using the IAuthorizationFilter allows us to use the base controller's 
//   built attribute handling.  We could have used result as well, but Auth seems
//   more appropriate.
public class ActiveAccountAttribute: FilterAttribute, IAuthorizationFilter
{

    #region IAuthorizationFilter Members

    public void OnAuthorization(AuthorizationContext filterContext)
    {

        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            return;

        // ... code which determines if our customer account is Active

        if (!user.Status.IsActive)
            filterContext.Result = new RedirectToRouteResult("Default", new RouteValueDictionary(new {controller = "Account"}));
    }

    #endregion
}

Upvotes: 3

Views: 1026

Answers (2)

Jirapong
Jirapong

Reputation: 24256

it should be two piece of code.

in your controller you return an error code by

Response.StatusCode = (int)HttpStatusCode.NotFound;

then you custom error code to desired route

<customErrors mode="On">
     <error statusCode="404" redirect="~/Profile/Update" />
</customErrors>

Upvotes: 0

Tomas Aschan
Tomas Aschan

Reputation: 60594

You could inherit the RedirectToRouteResult class and add a constructor parameter for the status code.

public class StatusRedirectResult : RedirectToRouteResult

    private string _status;

    public StatusRedirectResult(string action, RouteValueDictionary routeValues, string statusCode)
    {
        _status = statusCode;
        base.RedirectToRouteResult(action, routeValues);
    }

    public override ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Current.Response.Status = _status;
        base.ExecuteResult(context);
    }
}

To use this in a controller action, just

return StatusRedirect("NewAction", new RouteValueDictionary(new { controller = "TheController" }, "410");

Upvotes: 3

Related Questions