Reputation: 11243
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
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
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