.NET MVC 基于会话变量路由到特定区域控制器
.NET MVC Route to specific area controller based on a session variable
假设我正在为我的 Web 应用程序使用 MVC,并且我有一个包含多个控制器的区域...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
我知道我可以点击一个控制器并执行重定向,但是在堆栈的更高位置是否有我可以更好地控制控制器分配的地方。
阅读 MSDN 上的一篇文章后 https://msdn.microsoft.com/en-us/library/cc668201(v=vs.110).aspx 我想到了以下解决方案:
- 实现一个自定义的 MvcHandler 来处理选择的逻辑
控制器
- 实现 IRouteHandler
- 将 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();
}
假设我正在为我的 Web 应用程序使用 MVC,并且我有一个包含多个控制器的区域...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
我知道我可以点击一个控制器并执行重定向,但是在堆栈的更高位置是否有我可以更好地控制控制器分配的地方。
阅读 MSDN 上的一篇文章后 https://msdn.microsoft.com/en-us/library/cc668201(v=vs.110).aspx 我想到了以下解决方案:
- 实现一个自定义的 MvcHandler 来处理选择的逻辑 控制器
- 实现 IRouteHandler
- 将 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();
}