アプリには複数のテナントがあります。すべてのテナントには、ユーザーが認識できる短いコードが割り当てられています。URL でそのコードをルート パラメーターとして使用し、Ninject にテナントのデータベース接続文字列を含む DbContext をテナント固有のコントローラーに挿入させたいと考えています。
調べるために、私は CarController を持っており、すべてのテナントには独自の製品があります。URL は {tenantcode}/{controller}/{action} のようになります。この部分のやり方はわかりました。
ただし、テナントによってインスタンス化されるべきではないコントローラーがいくつかあります。具体的には、ホーム コントローラーと、ログイン/登録用のアカウント コントローラーです。これらは関係ありません。
したがって、必要な URL の例:
- myapp.com/ - ホームコントローラー
- myapp.com/Account/Login - AccountController
- myapp.com/GM/Car/Add - GM の DbContext が注入された CarController
- myapp.com/Ford/Car/Add - Ford の 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 }
);
}
}