如何在ASP.NET MVC 3中组合静态和动态视图

时间:2013-11-07 03:29:48

标签: asp.net-mvc-3

这是一个很难回答的问题,没有一些背景知道我想做什么。我正在研究现有的多租户ASP.NET MVC 3应用程序(数据应用程序的典型表单),但现在必须为租户提供向任何页面添加自定义字段的功能。所有租户都有一组固定的页面,但他们可以在其中一个页面的任何位置添加一个字段。例如,在具有输入地址字段的“用户配置文件”页面上,租户可能希望在“国家/地区”字段之前添加“县”字段。

每个租户的自定义字段的配置存储在一个数据库中,该数据库包含描述字段的内容(文本框,选择等)以及应该在何处呈现的信息,例如路径和字段的id应该在之前插入。

由于这是一个现有的应用程序,我有一些限制,并希望将所有现有的.cshtml视图保留为所有租户拥有的默认/基础。为了将租户特定字段添加到页面,我创建了一个自定义VirtualPathProvider:

  1. 从标准Views dir
  2. 加载.cshtm文件中定义的标准视图
  3. 从数据库加载视图的自定义字段定义(特定于发出请求的租户)
  4. 对于每个自定义字段,创建Razor标记并将其插入到第一步的加载视图中
  5. 返回现在同时具有基本和租户特定代码的组合视图
  6. 该设计适用于第一个视图请求,但是来自任何租户的后续请求只返回第一个版本。我很确定这里发生的事情是ASP.NET运行时正在编译和缓存视图,因此下一个视图请求就是从缓存中出来。

    所以最后这个问题。如何覆盖编译和缓存,以便包含租户ID等内容,以便每个租户缓存一次视图?

1 个答案:

答案 0 :(得分:0)

我发现你可以覆盖VirtualPathProviders的GetCacheKey方法来实现你自己的密钥模式。在我的例子中,将租户的密钥添加到缓存密钥的末尾,如下所示:

public override string GetCacheKey(string virtualPath)
{
    var tenantKey = getTenantKey();

    if (VirtualPathHelper.SupportsCustomFields(virtualPath))
    {
        return string.Join("_", virtualPath, tenantKey);
    }

    return base.GetCacheKey(virtualPath);
}

在ASP.NET Temporary Internet files目录中,该视图的文件名将是: _views_home_index.cshtml_a7c1a66a-ebe4-4ca2-8dc4-7a22b460f368.compiled

请求视图的每个租户现在都将获得自己的版本。