[英]How do I use routes for multi-tenancy in all but one controller?
我們的應用程序有多個租戶。 每個租戶都有一個分配給他們的短代碼,用戶可以通過它們了解他們。 我想將URL中的代碼用作路由參數,並讓Ninject將帶有租戶數據庫連接字符串的DbContext注入到特定於租戶的控制器中。
因此,為了進行檢查,我有一個CarController,每個租戶都有自己的產品。 URL看起來像{tenantcode} / {controller} / {action}。 我知道該怎么做。
但是,我有幾個控制器不應由租戶實例化。 具體地說,是家庭控制器和用於登錄/注冊的帳戶控制器。 這些沒關系。
因此,我需要以下示例URL:
如何從路由中排除某些控制器? 運行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 }
);
}
}
因此,據我所知,您在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,但這完全不應用任何路由規則,而是用於靜態資源。 希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.