3

我有两个 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被缩小和捆绑。即使我BundleTable.EnableOptimization = false在两个 BundleConfig.cs 文件中都使用,@Styles.Render()并且@Scripts.Render()仍然只呈现一个标签并引用被缩小的内容。

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

4

2 回答 2

4

所以我能够通过添加一个自定义 VirtualPathProvider 来实现这个工作,这使得主项目在静态内容项目中搜索单个文件。在调试模式下,文件将单独列出。在 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(); } }
    }
}
于 2014-03-17T20:18:40.507 回答
1

BundleTable.EnableOptimization = "false"不是事件在这里播放,因为您的主站点正在引用“捆绑包”,无论调试状态或 EnableOptimization 如何,它总是会被捆绑和缩小。

因此@Styles.Render("~/bundles/styles"),在静态站点上将呈现单个文件BundleTable.EnableOptimization = "false",但如果您直接导航到/bundles/styles,您仍然会获得缩小的捆绑包(您从主站点执行的操作)。

一种选择(可能是您唯一的选择)是在静态站点上配置捆绑器,以便在BundleTable.EnableOptimization = "false". 这可以通过编写一个继承自Bundle并使用它自己的自定义的类来完成IBundleBuilder(您甚至可以在将每个文件添加到包中时将文件名写为注释)。可以在 GitHub 上找到一些为您指明正确方向的示例代码。

于 2014-03-17T14:20:26.950 回答