.NET MVC基于会话变量路由到特定区域控制器

时间:2016-07-07 16:18:26

标签: asp.net-mvc asp.net-mvc-routing asp.net-session

让我说我使用MVC作为我的Web应用程序,我有一个包含多个控制器的区域...... MyController1 MyController2 MyController3

这些控制器由特定群组中的用户使用: UserGroup1 UserGroup2 UserGroup3 。我将在会话中存储组ID。

我希望客户端请求看起来像这样通用: www.mysite.com/MyArea/MyController/SomeAction

那么,如何根据会话中存储的组ID变量分配相应的控制器?

一些伪代码:

var id = HttpContext.Current.Session["GroupId"];
if id == 1
  use MyController1
else if id == 2 
  use MyController2
else if id == 3
  use MyController3

我知道我可以点击一个控制器并执行重定向,但是在堆栈中的某个位置,我可以更好地控制控制器分配。

1 个答案:

答案 0 :(得分:0)

在阅读MSDN https://msdn.microsoft.com/en-us/library/cc668201(v=vs.110).aspx上的文章后,我提出了以下解决方案:

  1. 实现一个自定义的MvcHandler,它将处理选择的逻辑 控制器
  2. 实施IRouteHandler
  3. 将IRouteHandler附加到AreaRegistration
  4. 中注册的路由
    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);
            }
    }
    

    最后,注册RouteHandler:

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "default",
                "{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            ).RouteHandler = new MyRouteHandler();            
        }