【问题标题】:Get access to the URL's being used in System.Web.Optimization访问 System.Web.Optimization 中使用的 URL
【发布时间】:2014-07-07 09:23:18
【问题描述】:

背景:我正在使用 HTML 5 Offline App Cache 并动态构建清单文件。基本上,清单文件需要列出您的页面将请求的每个静态文件。当文件实际上是静态的时效果很好,但我在 System.Web.Optimization 中使用捆绑和缩小,所以我的文件不是静态的。

当在 DEBUG 中加载符号时(即在 VS 中调试),然后从 MVC 视图中调用实际的物理文件。然而,当处于发布模式时,它会调用一个看起来像这样的虚拟文件:/bundles/scripts/jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1

所以我的问题:如何在代码中获取该 URL 以将其添加到离线应用清单?

我试过了:

        var paths = new List<string>()
        {
            "~/bundles/styles/common",
            "~/bundles/styles/common1024",
            "~/bundles/styles/common768",
            "~/bundles/styles/common480",
            "~/bundles/styles/frontend",
            "~/bundles/scripts/jquery",
            "~/bundles/scripts/common",
            "~/bundles/scripts/frontend"
        };

        var bundleTable = BundleTable.Bundles;
        foreach (var bundle in bundleTable.Where(b => paths.Contains(b.Path)))
        {
            var bundleContext = new BundleContext(this.HttpContext, bundleTable, bundle.Path);
            IEnumerable<BundleFile> files = bundle.GenerateBundleResponse(bundleContext).Files;
            foreach (var file in files)
            {
                var filePath = file.IncludedVirtualPath.TrimStart(new[] { '~' });
                sb.AppendFormat(formatFullDomain, filePath);
            }
        } 

除了将GenerateBundleResponse() 替换为EnumerateFiles(),它总是返回原始文件路径。

我也愿意接受替代实施建议。谢谢。

更新:(2014 年 7 月 7 日 13:45)

除了下面的答案,我还添加了这个 Bundles Registry 类来保存所需静态文件的列表,以便它在所有浏览器中以调试模式工作。 (见下面的cmets)

    public class Registry
    {
        public bool Debug = false;
        public Registry()
        {
            SetDebug();
        }
        [Conditional("DEBUG")]
        private void SetDebug()
        {
            Debug = true;
        }

        public IEnumerable<string> CommonScripts
        {
            get
            {
                if (Debug)
                {
                    return new string[]{
                        "/scripts/common/jquery.validate.js",
                        "/scripts/common/jquery.validate.unobtrusive.js",
                        "/scripts/common/knockout-3.1.0.debug.js",
                        "/scripts/common/jquery.timepicker.js",
                        "/scripts/common/datepicker.js",
                        "/scripts/common/utils.js",
                        "/scripts/common/jquery.minicolors.js",
                        "/scripts/common/chosen.jquery.custom.js"
                    };
                }
                else
                {
                    return new string[]{
                        "/scripts/common/commonbundle.js"
                    };
                }
            }
        }
    }

我对这个解决方案一点也不满意。如果您可以改进这一点,请提出建议。

【问题讨论】:

    标签: c# asp.net asp.net-mvc bundling-and-minification web-optimization


    【解决方案1】:

    我可以从这篇博文create your own token 中提出替代方案。

    总的来说,作者建议使用web essentials 创建捆绑文件,然后创建一个剃刀助手来生成令牌,在这种情况下基于上次更改的日期和时间。

    public static class StaticFile
    {
        public static string Version(string rootRelativePath)
        {
            if (HttpRuntime.Cache[rootRelativePath] == null)
            {
                var absolutePath = HostingEnvironment.MapPath(rootRelativePath);
                var lastChangedDateTime = File.GetLastWriteTime(absolutePath);
    
                if (rootRelativePath.StartsWith("~"))
                {
                    rootRelativePath = rootRelativePath.Substring(1);
                }
    
                var versionedUrl = rootRelativePath + "?v=" + lastChangedDateTime.Ticks;
    
                HttpRuntime.Cache.Insert(rootRelativePath, versionedUrl, new CacheDependency(absolutePath));
            }
    
            return HttpRuntime.Cache[rootRelativePath] as string;
        }
    }
    

    然后你可以像这样引用捆绑的文件...

    @section scripts {
    <script src="@StaticFile.Version("~/Scripts/app/myAppBundle.min.js")"></script>}
    

    然后你就可以控制令牌,并且可以用它做你想做的事情。

    【讨论】:

    • 感谢您的回答。它看起来确实很容易,但是当我调试时呢?我希望在调试模式下单独请求单个文件并且不缩小文件。有什么建议吗?
    • 我看到它添加了 js 源映射,但这仅在客户端调试器支持源映射时才有用——据我所知,Firebug 不支持。我可以停止使用 firebug,而只使用内置的 firefox 调试器,但这似乎有点飞跃,以解决一个问题。有没有办法修改“StaticFile.Version()”方法以仅在不处于调试模式时调用捆绑包?我会做一些工作并发布任何更新。
    • 好的,这似乎是最好的解决方案。尽管您无法在优化 API 中访问似乎很奇怪。我会更喜欢那个解决方案,因为如果我需要将此项目传递给其他人,他们就不需要安装 Web Essentials。我在上面发布了更新以显示我的最终结果。
    猜你喜欢
    • 2020-04-09
    • 2017-03-24
    • 2017-08-14
    • 1970-01-01
    • 2023-03-22
    • 2012-07-03
    • 2012-12-12
    • 2011-04-11
    • 2017-12-11
    相关资源
    最近更新 更多