2013-10-25 30 views
1

我们的应用程序有多个租户。每个租户都有一个简短的代码分配给用户,他们知道他们。我想用我的网址,该代码作为参数路线,并有Ninject注入的DbContext与租户的数据库连接字符串到承租人专用的控制器。如何在除一个控制器之外的所有控制器中使用多租户路由?

所以对检查我有一个CarController,每个租户都有自己的产品。这些网址看起来像{tenantcode}/{controller}/{action}。我明白如何做到这一点。

不过,我有几个控制器不应该由房客来实例化。具体来说就是用于登录/注册的家庭控制器和帐户控制器。这些都不重要。

所以例如网址,我需要:

  • myapp.com/ - HomeController的
  • myapp.com/Account/Login - 的AccountController
  • myapp.com/GM/Car/Add - CarController有通用汽车公司的DbContext注入
  • myapp.com/Ford/Car/Add - CarController有福特的DbContext注入

我怎样才能排除某些控制器从路线?运行ASP.NET MVC 5.


非常感谢Darko Z让我朝着正确的方向开始。我结束了使用传统路线的混合,并在MVC新属性的路由5.

首先,“排除”路线得到了装饰与新RouteAttribute类

public class HomeController : Controller 
{ 
    private readonly TenantContext context; 

    public HomeController(TenantContext Context) 
    { 
     this.context = Context; 
    } 

    // 
    // GET: http://myapp.com/ 
    // By decorating just this action with an empty RouteAttribute, we make it the "start page" 
    [Route] 
    public ActionResult Index(bool Error = false) 
    { 
     // Look up and make a nice list of the tenants this user can access 
     var tenantQuery = 
      from u in context.Users 
      where u.UserId == userId 
      from t in u.Tenants 
      select new 
      { 
       t.Id, 
       t.Name, 
      }; 

     return View(tenantQuery); 
    } 
} 

// By decorating this whole controller with RouteAttribute, all /Account URLs wind up here 
[Route("Account/{action}")] 
public class AccountController : Controller 
{ 
    // 
    // GET: /Account/LogOn 
    public ActionResult LogOn() 
    { 
     return View(); 
    } 

    // 
    // POST: /Account/LogOn 
    [HttpPost] 
    public ActionResult LogOn(LogOnViewModel model, string ReturnUrl) 
    { 
     // Log on logic here 
    } 
} 

接下来,我注册Darko Z建议的租户通用路线。在制作其他路线之前调用MapMvcAttributeRoutes()是很重要的。这是因为我的属性基于路线是“例外”,和他说的那样,这些例外必须是在顶部,以确保他们的第一次拿起。

public class RouteConfig 
{ 
    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     // exceptions are the attribute-based routes 
     routes.MapMvcAttributeRoutes(); 

     // tenant code is the default route 
     routes.MapRoute(
      name: "Tenant", 
      url: "{tenantcode}/{controller}/{action}/{id}", 
      defaults: new { controller = "TenantHome", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
} 

回答

2

因此,我相信你知道你在MVC中按照从最具体到最通用的顺序指定路由。所以你的情况我会做这样的事情:

//exclusions - basically hardcoded, pacing this at the top will 
//ensure that these will be picked up first. Of course this means 
//you must make sure that tenant codes cannot be the same as any 
//controller name here 
routes.MapRoute(
    "Home",            
    "Home/{action}/{id}",       
    new { controller = "Home", action = "Index", id = "" } 
); 

routes.MapRoute(
    "Account",            
    "Account/{action}/{id}",       
    new { controller = "Account", action = "Index", id = "" } 
); 

//tenant generic route 
routes.MapRoute(
    "Default",            
    "{tenantcode}/{controller}/{action}",       
    new { tenantcode = "Default", controller = "Tenant", action = "Index" } 
); 

//default route 
routes.MapRoute(
    "Default",            
    "{controller}/{action}/{id}",       
    new { controller = "Home", action = "Index", id = "" } 
); 

这显然是唯一的好,如果有小于排除控制器比需要的租户代码控制器。如果没有,那么你可以采取相反的做法,并扭转上述情况。这里主要的东西是(很高兴被证明是错误的)在AddRoute调用中没有办法通用忽略。虽然存在IgnoreRoute,但它完全不适用任何路由规则并用于静态资源。希望有所帮助。

相关问题