访问System.Web.Optimization中正在使用的url

本文关键字:url System Web Optimization 访问 | 更新日期: 2023-09-27 18:11:39

Background:我正在使用HTML 5离线应用程序缓存并动态构建清单文件。基本上,清单文件需要列出页面将请求的每个静态文件。当文件实际上是静态的时候工作得很好,但是我在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(),但它总是返回原始文件路径。

我也愿意接受其他实现建议。谢谢。

UPDATE: (7/7/14 13:45)

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

    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"
                    };
                }
            }
        }
    }

我对这个解决方案一点也不满意。

访问System.Web.Optimization中正在使用的url

我可以从这篇博客文章中提出一个替代方案:创建您自己的令牌。

总之,作者建议使用web essentials创建捆绑文件,然后创建razor helper来生成令牌,在这种情况下,基于最后更改的日期和时间。

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>}

然后你就可以控制这个令牌了,你可以用它做你想做的事情。