Lets say I am using MVC for my web application and I have an area that contains multiple controllers... MyController1, MyController2 and MyController3
These controllers are used by users in certain groups: UserGroup1, UserGroup2 and UserGroup3. I will store the group id in the session.
I would like the client requests to look generic like this: www.mysite.com/MyArea/MyController/SomeAction
So, how do I assign the respective controller based on the group id variable stored in session?
some pseudo code:
var id = HttpContext.Current.Session["GroupId"];
if id == 1
use MyController1
else if id == 2
use MyController2
else if id == 3
use MyController3
I know I could hit a controller and perform a redirect, but is there somewhere higher up in the stack that I can have more control over the controller assignment.
After reading an article on MSDN https://msdn.microsoft.com/en-us/library/cc668201(v=vs.110).aspx I came up with the following solution:
public class MyRouteHandler : IRouteHandler
{
IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
{
return new MyMvcHandler(requestContext);
}
}
public class MyMvcHandler : MvcHandler, IHttpHandler
{
public MyMvcHandler(RequestContext requestContext) : base(requestContext)
{
}
private string GetControllerName(HttpContextBase httpContext)
{
string controllerName = this.RequestContext.RouteData.GetRequiredString("controller");
var groupId = httpContext.Session["GroupId"] as string;
if (!String.IsNullOrEmpty(groupId) && !String.IsNullOrEmpty(controllerName))
{
controllerName = groupId + controllerName;
}
return controllerName;
}
protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
{
RequestContext.RouteData.Values["controller"] = this.GetControllerName(httpContext);
return base.BeginProcessRequest(httpContext, callback, state);
}
}
and finally, register the RouteHandler:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"default",
"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
).RouteHandler = new MyRouteHandler();
}