asp.net - 使用无 cookie 静态内容服务器时,如何使 bundle 解压缩并列出单个文件?

标签 asp.net asp.net-mvc asp.net-mvc-4 bundling-and-minification system.web.optimization

我有两个 VS 项目,一个用于主网站,另一个用于“静态内容”网站,其中所有 css、js、图像和其他静态内容都将通过无 cookie 域存储和访问。

所以我的静态站点中有一个 BundleConfig.cs 用于创建所有包:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new StyleBundle("~/bundles/styles").IncludeDirectory("~/app/styles", "*.css", true));
        bundles.Add(new ScriptBundle("~/bundles/scripts").IncludeDirectory("~/app/src", "*.js", true));
    }
}

在主站点中,我有另一个 BundleConfig.cs,我将主站点指向静态内容站点,如下所示:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        var staticWebsite = ConfigurationManager.AppSettings["StaticWebsite"];
        var versionNumber = ConfigurationManager.AppSettings["VersionNumber"];

        Styles.DefaultTagFormat = string.Format("<link href='{0}{{0}}?v={1}' rel='stylesheet'/>", staticWebsite, versionNumber);
        Scripts.DefaultTagFormat = string.Format("<script src='{0}{{0}}?v={1}'></script>", staticWebsite, versionNumber);

    }
}

现在我可以使用 @Styles.Render("~/bundles/styles")@Scripts.Render("~/bundles/scripts") 进行渲染像这样,正是我想要的方式,而且效果很好:

<link href='http://mycookielessdomain.com/bundles/styles?v=1.0.0.0' rel='stylesheet'/>
<script src='http://mycookielessdomain.com/bundles/scripts?v=1.0.0.0'></script>

我遇到的问题是,无论 debug=true 与否,内容总是被缩小和捆绑。即使我在两个 BundleConfig.cs 文件中使用 BundleTable.EnableOptimization = false@Styles.Render()@Scripts.Render()仍然只渲染每个标签并引用缩小的内容。

我知道主站点不知道静态内容站点中捆绑的各个文件,但我希望有某种方法可以在主站点 BundleConfig 中手动指定这些路径,以便 Render( ) 方法可以在优化关闭时单独列出它们...如果我能让它们关闭的话。

最佳答案

因此,我能够通过添加自定义 VirtualPathProvider 来实现此功能,该自定义 VirtualPathProvider 使主项目在静态内容项目中搜索各个文件。当处于 Debug模式时,文件会单独列出。当处于 RELEASE 模式时,将引用缩小的包。

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        var staticWebsite = ConfigurationManager.AppSettings["StaticWebsite"];
        var versionNumber = ConfigurationManager.AppSettings["VersionNumber"];

        Styles.DefaultTagFormat = string.Format("<link href='{0}{{0}}?v={1}' rel='stylesheet'/>", staticWebsite, versionNumber);
        Scripts.DefaultTagFormat = string.Format("<script src='{0}{{0}}?v={1}'></script>", staticWebsite, versionNumber);

#if DEBUG
        // Includes files from the static content project so they can be listed individually if in DEBUG mode.
        BundleTable.VirtualPathProvider = new StaticContentVirtualPathProvider();
        bundles.Add(new StyleBundle("~/bundles/styles").IncludeDirectory("~/app/styles", "*.css", true));
        bundles.Add(new ScriptBundle("~/bundles/scripts").IncludeDirectory("~/app/src", "*.js", true));
#endif
    }
}

这是我的自定义 VirtualPathProvider:

public class StaticContentVirtualPathProvider : VirtualPathProvider
{
    // Modify this to be the relative path from your main project to your static content project.
    private const string StaticContentRelativePath = @"..\..\MyStaticContentProjectFolder";

    public static string GetStaticContentPath(string virtualPath, bool isDirectory = false)
    {
        virtualPath = virtualPath.Replace('/', '\\').Replace("~", "");

        if (isDirectory && !virtualPath.EndsWith("\\")) virtualPath += "\\";

        return HttpRuntime.AppDomainAppPath + StaticContentRelativePath + virtualPath;
    }

    public override bool FileExists(string virtualPath)
    {
        return File.Exists(GetStaticContentPath(virtualPath));
    }

    public override bool DirectoryExists(string virtualDir)
    {
        return Directory.Exists(GetStaticContentPath(virtualDir));
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        return new StaticContentVirtualFile(virtualPath);
    }

    public override VirtualDirectory GetDirectory(string virtualDir)
    {
        return new StaticContentVirtualDirectory(virtualDir);
    }

    private class StaticContentVirtualFile : VirtualFile
    {
        public StaticContentVirtualFile(string virtualPath)
            : base(virtualPath)
        {
            this.virtualPath = virtualPath;
        }

        private readonly string virtualPath;

        public override Stream Open()
        {
            return new FileStream(StaticContentVirtualPathProvider.GetStaticContentPath(virtualPath), FileMode.Open);
        }
    }

    internal class StaticContentVirtualDirectory : VirtualDirectory
    {
        public StaticContentVirtualDirectory(string virtualPath)
            : base(virtualPath)
        {
        }

        public override IEnumerable Files
        {
            get
            {
                var filePaths = Directory.GetFiles(GetStaticContentPath(this.VirtualPath, true));
                var files = filePaths.Select(filePath => new StaticContentVirtualFile(this.VirtualPath + Path.GetFileName(filePath))).ToList();
                return files;
            }
        }

        public override IEnumerable Directories
        {
            get
            {
                var subDirectoryPaths = Directory.GetDirectories(GetStaticContentPath(this.VirtualPath, true));
                var dirs = subDirectoryPaths.Select(subDirectoryPath => new StaticContentVirtualDirectory(this.VirtualPath + Path.GetFileName(subDirectoryPath))).ToList();
                return dirs;
            }
        }

        public override IEnumerable Children { get { throw new NotImplementedException(); } }
    }
}

关于asp.net - 使用无 cookie 静态内容服务器时,如何使 bundle 解压缩并列出单个文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22390241/

相关文章:

ASP.NET HttpApplication生命周期

c# - 如何使用 SQL 将表中的多个 ID 与 INNER JOIN 结合使用?

html - 布局/HTML 中的 MVC 4 错误

asp.net-mvc - 将模型传递给 RedirectToAction()

c# - 让存储在 Session 中的数据保持事件状态

sql-server - 没有定义主键并且无法推断出有效的主键

asp.net-mvc-4 - MVC4 Html.DropDownListFor 在循环中未设置所选选项

asp.net - asp.net 中的嵌套 css 值

c# - MVC JSON 数据引用

javascript - javascript 错误 500 内部服务器错误