views:

71

answers:

2

So inside my ASP.NET MVC View I have a conditional statement to redirect users to a different page.

What is the best way to do this?

What is the Controller.RedirectToAction() equivalent for a View?

A: 

Your best option would likely be to move the conditional to your Controller and perform the redirection there (this also makes the redirection logic easy to test). Alternatively, you could wrap a JavaScript statement with your View's server-side conditional like so:

<% if (viewShouldRedirect) { %>
    <script type="text/javascript">
        window.location = "/Your/New/Url";
    </script>
<% } %>
TimGThomas
Yes, this would work. Although if the user has JS disabled (NoScript or wotnot), then this wouldn't work.
Dan Atkinson
+1 for moving the logic to the controller. No reason to even render the view to the browser if you are just going to redirect.
tvanfosson
Yeah JS won't fly because if they don't have it then they can still get in, the idea is role checking inside of my Master page... if I do it elsewhere I will have to code into each Action... and remember to do it in all of them from here on out, was hoping for a silver bullet by putting the check/redirect into the master page.
shogun
That sounds like a perfect use for an ActionFilter, then. You can decorate all your Actions with it and it can automatically redirect if necessary.
TimGThomas
hmm I will look into this ActionFilter, thanks
shogun
Have you checked out the Authorize attribute? http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx
TimGThomas
yeah but the users ARE Authorize by the time they get there, just need to prevent the ones with the lower Roles from getting in
shogun
@Ryan. If you're preventing users from accessing that page, than they are NOT Authorized. They may be authenticated, but that's not the same as authorization.
Jace Rhea
+4  A: 

This sounds like a perversion of MVC and if you can't do the redirect in the controller, then your logic is not correct.

However, here is what I would use if I didn't have access to the controller for whatever reason:

<meta http-equiv="refresh" content='0;url=<%=Html.Action("MyAction","MyController") %>'>

Update

In your comment, you mentioned it's because you're doing role checking and you don't want to do this in every controller/action. If that's the case, then here is something that you might like to consider:

Create a base controller class and have every controller extend from this class.

In your base controller, have an OnActionExecuting method. In here, you have something like this:

public class MyBaseController : Controller
{
  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
     base.OnActionExecuting(filterContext);
     if (/*the user is not in the role desired*/)
     {
       RedirectToRoute(filterContext, new { controller = "MyController", action = "MyAction"});
    }
  }

  private void RedirectToRoute(ActionExecutingContext context, object routeValues)
  {
    var rc = new RequestContext(context.HttpContext, context.RouteData);
    string url = RouteTable.Routes.GetVirtualPath(rc, new RouteValueDictionary(routeValues)).VirtualPath;
    context.HttpContext.Response.Redirect(url, true);
  }
}
Dan Atkinson
it's a role checking thing and I don't want to code it into every single action when I can just do it in my master page and be done with it
shogun
Okay. Well, I've updated the meta tag which to display a Html.Action. This should do everything you need it to.
Dan Atkinson
Ah so I will need to add this to the <head> I can't just do it anywhere in the view? is there not a way? I guess HTML is what it is, thanks
shogun
I've updated the comment again to reflect your needs. This would a better solution, but as mentioned by TimGThomas, actionfilters are also a good idea/better than mine.
Dan Atkinson
@Ryan Putting logic in your view is a perversion of MVC, as the answerer said.
George Stocker
ugh you guys are right, I just realized in testing that I can hit the STOP button on my browser before the redirect happens... guess I have to do it the hard way :)
shogun
I'd go custom ActionFilter all the way.
DM
ooo we already do have a base controller for everything, so this new edit may be really feasible, thanks
shogun