2013-10-25 74 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,但它完全不適用任何路由規則並用於靜態資源。希望有所幫助。

相關問題