如果我理解正确,用户可以同时打开 2 个不同的选项卡,每个选项卡都有不同的租户。每个页面都应该显示与每个租户相关的数据。
因此,这意味着需要丢弃涉及 cookie 或会话的解决方案,因为租户特定于每个浏览器选项卡。
并阅读您对 Cyril Gupta 建议的回答,我了解每个页面上隐藏的tenantId 可能不会在每个 AJAX 请求上提交。当然,一种解决方案可能是修改您的应用程序并确保每个 AJAX 请求始终如此。否则,这也会丢弃基于请求参数的全局过滤器,因为可能并不总是存在租户 ID。
我认为最好的选择是在包含tenantId的URL中添加一个段。例如,将默认路由替换为以下路由(如果您有许多不同的路由,则需要非常小心以避免路由冲突):
routes.MapRoute(
name: "Default",
url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant = "defaultTenant", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
通过这种方式,您可以确保在每个请求中始终提交租户,并且您还可以有 2 个不同的选项卡,其中不同的租户显示每个相应的数据。
关于如何恢复路线段的价值有不同的选择。
绑定将自动填充操作方法上任何名为“租户”的参数的值,或作为操作方法参数的模型类中的任何名为“租户”的参数: public ActionResult Foo(FooModel model, string tenant) { //tenant 和 model.tenant 都将包含 URL 段的值 return View(); }
您还可以编写一个过滤器来访问路由参数的值(RouteData 是作为过滤器方法的参数接收的ActionExecutingContext
和ActionExecutedContext
类的属性),并执行一些逻辑。然后过滤器将在您的应用程序或您的基本控制器中设置为全局过滤器:
public class FooFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var tenant = filterContext.RouteData.Values["tenant"]
//do whatever you need to do before executing the action, based on the tenant
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var tenant = filterContext.RouteData.Values["tenant"]
//do whatever you need to do after executing the action, based on the tenant
}
}
最后一个选项是直接访问基础控制器类上的 RouteData 参数。(因为 RouteData 是基础 MVCController
类的属性)
只要您使用 Html 和 Ajax 帮助器生成 URL,URL 的租户段就会保留在您的链接中。但是,如果您有 jquery 代码直接发送带有硬编码 URL 的 AJAX 调用,那么您需要更新该代码以便考虑新的 url 段。
最后,如果tenantId 值不是非常用户友好的值(例如整数),您可以为每个租户设置唯一名称并使用URL 中的名称。然后,您将添加一些逻辑,将其映射到您的应用程序需要的整数值。