如果我理解正确的话,用户可以同时打开两个不同租户的标签页。每个页面都应显示与各自租户相关的数据。
这意味着涉及cookie或会话的解决方案需要被舍弃,因为租户是特定于每个浏览器标签页的。
阅读您对Cyril Gupta建议的回答后,我了解到每个页面上的隐藏tenantId可能不会在每个AJAX请求中提交。当然,一种解决方案是修改您的应用程序,并确保在每个AJAX请求中始终如此。否则,基于请求参数的全局过滤器也将被舍弃,因为tenantId可能不总是存在。
我认为最好的选择是在URL中添加一个包含tenantId的段落。例如,使用以下路由替换默认路由(如果您有许多不同的路由,则需要非常小心以避免路由冲突):
routes.MapRoute(
name: "Default",
url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant = "defaultTenant", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
这样,您可以确保每个请求都会提交租户,并且您还可以拥有两个不同的选项卡,显示各自相应的数据。
有不同的选项来恢复路由段的值。
绑定将自动填充任何命名为“tenant”的参数的值到您的操作方法中,或者填充任何模型类中作为操作方法参数的参数命名为“tenant”的值:
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"]
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var tenant = filterContext.RouteData.Values["tenant"]
}
}
最后一种选择是直接访问您的基础控制器类上的RouteData参数。(因为RouteData是基础MVC Controller类的属性)
只要您使用Html和Ajax助手生成URL,URL的租户段就会在您的链接中保留。但是,如果您有jquery代码直接发送带有硬编码URL的AJAX调用,则需要更新该代码以考虑新的url段。
最后,如果tenantId值不太用户友好,例如整数,则可以为每个租户设置唯一名称并在URL中使用这些名称。然后,您将添加一些逻辑,将其映射到应用程序所需的整数值。