【问题标题】:ASP.NET Bundling and minification include dynamic files from databaseASP.NET 捆绑和缩小包括来自数据库的动态文件
【发布时间】:2012-12-31 18:00:16
【问题描述】:

我正在开发一个多租户 MVC 4 应用程序,用户可以在该应用程序上进行一些主题化。
他可以通过向主题表添加相对路径来覆盖每个资源(css、js、jpg、png 等),例如/Scripts/booking.js

使用哪个租户由 URL 确定,例如http://myapp/tenant/Booking/New 这只是应该使用的连接字符串的名称。

因此,如果对特定资源提出请求,我首先需要检查数据库中是否存在此资源的覆盖版本,如果找到则使用它。

现在我想实现微软在 System.Web.Optimization 命名空间中提供的新捆绑和缩小功能。但是我不知道如何使用数据库中的文件来实现这一点。

我已经制作了自己的 JsMinify 实现原型来实现这一目标

public class MyJsMinify : JsMinify
{
    private static byte[] GetContentFile(FileInfo filePath)
    {
        string fullName = filePath.FullName;
        int indexOf = fullName.IndexOf("content", StringComparison.OrdinalIgnoreCase);
        string substring = fullName.Substring(indexOf + 8).Replace(@"\\", "/").Replace(@"\", "/");

        ThemingService themingService = ObjectFactory.GetInstance<ThemingService>();
        Theming myTheming = themingService.Find(new ThemingFilter { FilePathLike = substring });
        if (myTheming == null)
        {
            return themingService.GetContentFile(fullName);
        }
        return myTheming.FileData;
    }

    public override void Process(BundleContext context, BundleResponse response)
    {
        StringBuilder newContent = new StringBuilder();
        foreach (FileInfo fileInfo in response.Files)
        {
            using (MemoryStream memoryStream = new MemoryStream(GetContentFile(fileInfo)))
            {
                using (StreamReader myStreamReader = new StreamReader(memoryStream, true))
                {
                    newContent.AppendLine(myStreamReader.ReadToEnd());
                }
            }
        }

        response.Content = newContent.ToString();

        base.Process(context, response);
    }
}

如果我处于发布模式,这似乎可行,但在开发过程中,我希望独立引用每个脚本。这是在整个捆绑和缩小框架中自动完成的。框架生成的资源 URL 如下所示

<script src="/myapp/Content/Scripts/jquery-1.9.0.js"></script>

但应该是这样的

<script src="/myapp/tenant/Content/Scripts/jquery-1.9.0.js"></script>

我已经配置了以下路由:

routeCollection.MapRoute("Content1", "{mandator}/Content/{*filePath}", new { mandator = defaultMandator, controller = "Environment", action = "ContentFile" }, new { mandator = mandatorConstraints });
routeCollection.MapRoute("Content2", "Content/{*filePath}", new { mandator = defaultMandator, controller = "Environment", action = "ContentFile" }, new { mandator = mandatorConstraints });

ContentFile 方法如下所示

    [AcceptVerbs(HttpVerbs.Get)]
    [AcceptType(HttpTypes.All)]
    [OutputCache(CacheProfile = "ContentFile")]
    public ActionResult ContentFile(string filePath)
    {
        if (string.Compare(filePath, "Stylesheets/Import.css", StringComparison.OrdinalIgnoreCase) == 0)
        {
            return GetContentImport(CssFileArray, "Stylesheets/");
        }
        if (string.Compare(filePath, "Stylesheets/ImportOutlook.css", StringComparison.OrdinalIgnoreCase) == 0)
        {
            return GetContentImport(OutlookCssFileArray, "Stylesheets/");
        }
        if (string.Compare(filePath, "Scripts/OutlookAddin/Import.js", StringComparison.OrdinalIgnoreCase) == 0)
        {
            return GetContentImport(OutlookJsFileArray, "Scripts/");
        }
        return new FileContentResult(GetContentFile(filePath), MimeType(filePath));
    }

有人知道我如何实现这一目标吗?
是否有可遵循的多租户模式?

【问题讨论】:

    标签: asp.net-mvc-4 multi-tenant bundling-and-minification


    【解决方案1】:

    所以我不确定我是否完全理解您的情况,但我相信这就是 VirtualPathProviders 可以用于的用途。

    我们在 1.1-alpha1 版本中添加了支持,因此捆绑软件将自动使用在 ASP.NET 中注册的 VirtualPathProvider 来获取文件的内容。

    如果您要编写一个能够始终返回正确版本的 ~/Scripts/booking.js 的自定义 VPP,那么一切都应该正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多