0

假设我在我的 Web 应用程序中使用 MVC,并且我有一个包含多个控制器的区域...... MyController1MyController2MyController3

这些控制器由某些组中的用户使用:UserGroup1UserGroup2UserGroup3。我会将组 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

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

4

1 回答 1

1

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

  1. 实现一个自定义 MvcHandler 来处理选择控制器的逻辑
  2. 实现 IRouteHandler
  3. 将 IRouteHandler 附加到在 AreaRegistration 中注册的路由

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();            
    }
于 2016-07-07T21:49:48.377 回答