我可以使用全局过滤器处理不同的多租户吗?

时间:2011-03-10 14:07:49

标签: asp.net-mvc asp.net-mvc-3 multi-tenant action-filter

我有一个asp.net mvc应用程序,已实现成员资格。 因此用户必须登录。每个用户都属于一个组织(多租户)。

我如何处理组织参数globaly?我认为这对于全局过滤器来说可能是一件好事,因为需要针对给定的组织过滤所有数据。组织与用户名相关联,但不在同一个表中。

例如我有一个像这样的索引动作

public ActionResult Index()
{
var result = _repository.GetListByOrganisation(organisation);
return View(result);
}

我正在考虑拥有一个全局属性,它根据给定的用户名查询组织的数据库。由于我的控制器已经包含authorize属性,因此我有用户名。在每个请求上缓存组织(session,controllercontext)并且不从db查询组织会很好。

这是实现这样的方法吗?或者还有其他更好的方法吗?如何在过滤器中设置控制器/ controllercontext上的属性?

所以对此以及评论的任何想法都会很棒......

2 个答案:

答案 0 :(得分:2)

我会通过DI来做到这一点。

您可以使用第三方DI容器或您自己的代码。无论哪种方式,您都希望在每个请求的基础上设置组织ID。

因此,您将创建一个工作单元并将其注入控制器中。为简单起见,我们假设您的工作单元是示例代码中的_repository字段,即使大多数真实世界的应用程序都比较复杂。

您将构造函数参数添加到控制器:

public FooController(IFooRepository repository)
{
    this._repository = repository;
}

...以及FooRepository上的组织ID:

public class FooRepository: IFooRepository
{
    public FooRepository(long organizationId)
    {
        this._organizationId = organizationId;
    }
}

现在,无论是DI容器设置还是MVC控制器工厂,都可以设置全部:

builder.Register(c => new FooRepository(GetOrgIdForCurrentUser()).As<IFooRepository>();
builder.Register(c => new FooController(c.Resolve<IFooRepository>());

答案 1 :(得分:1)

也许您可以将该组织嵌入到网址中,例如,如果您的路线如下/ {organization} / {controller} / {action}

然后你会得到像

这样的网址
  • / bigorg / products / list
  • / smallorg /产品/列表

您将在控制器中收到组织参数或RouteData对象的组织。