Conditional ASP.NET MVC 3 Routing (With Areas)
Hurro.
I'm trying to achieve some conditional routing based on whether the current user is an admin or not. The system only has two modes, admin or non-admin and nothing more than this. I'm using areas for my admin area because the controller names would be the same, but they'll deliver different functionality pretty much in every case.
In this system, however, the admins shouldn't really be aware of their admin location, they just know that they use the system to do something else other than what regular users do. I don't want there to be any distinction between the two in terms of URL because of this. What I want to do is be able to do something like mysite.com/AuditHistory and dependant on whether you're an admin or user will depend on what controller is used. So if it's a user making this request, then it'd use the AuditHistoryController
in the regular controllers folder, but if it's an admin then it'd use the AuditHistoryController
in Areas/Admin/Controllers.
I've seen the use of IRouteConstraint
and can do something along the following lines:
public class AdminRouteConstraint : IRouteConstraint
{
public AdminRouteConstraint() { }
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return httpContext.User.IsInRole("Admin");
}
}
With the following:
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", controller = "Home", id = UrlParameter.Optional },
new { controller = new AdminRouteConstraint() }
);
Can I simply get rid of "Admin/" at the front and do the same thing for the other routes but say UserRouteConstraint
? I've开发者_StackOverflow not seen this done anywhere though and not sure if it's correct.
Any ideas on how to do this?
Could you simply redirect the user from the ActionResult
if they are in a role? That is if you don't mind the URL changing?
Something like this...
[Authorize]
public ActionResult AuditHistory()
{
if(Context.User.IsInRole("Admin")
{
return Redirect("Admin/AuditHistory");
}
else
{
return View();
}
}
To me, this is a bit of a hack. But it may be a solution.
Obviously, you would need to do basic checks like making sure the current request is authenticated etc.
If you really don't want the URL to change, you could possibly have two separate views and do away with the admin Area
[Authorize]
public ActionResult AuditHistory()
{
if(Context.User.IsInRole("Admin")
{
return View("AdminAuditHistory", new AdminAuditHistoryViewModel());
}
else
{
return View("AuditHistory", new AuditHistoryViewModel());
}
}
In fact I think this is probably the cleanest solution, but is possibly still a bit of a hack.
I hope this helps.
精彩评论