簡體   English   中英

如何在一個控制器之外的所有控制器中使用路由進行多租戶?

[英]How do I use routes for multi-tenancy in all but one controller?

我們的應用程序有多個租戶。 每個租戶都有一個分配給他們的短代碼,用戶可以通過它們了解他們。 我想將URL中的代碼用作路由參數,並讓Ninject將帶有租戶數據庫連接字符串的DbContext注入到特定於租戶的控制器中。

因此,為了進行檢查,我有一個CarController,每個租戶都有自己的產品。 URL看起來像{tenantcode} / {controller} / {action}。 我知道該怎么做。

但是,我有幾個控制器不應由租戶實例化。 具體地說,是家庭控制器和用於登錄/注冊的帳戶控制器。 這些沒關系。

因此,我需要以下示例URL:

  • myapp.com/-HomeController
  • myapp.com/Account/Login-AccountController
  • myapp.com/GM/Car/Add-注入了GM的DbContext的CarController
  • myapp.com/Ford/Car/Add-已注入福特DbContext的CarController

如何從路由中排除某些控制器? 運行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM