Получить доступ к URL-адресу, используемому в System.Web.Optimization

Предыстория: я использую кэш автономного приложения HTML 5 и динамически создаю файл манифеста. По сути, файл манифеста должен содержать список всех статических файлов, которые запрашивает ваша страница. Прекрасно работает, когда файлы на самом деле статичны, но я использую Bundling and Minification в System.Web.Optimization, так что мои файлы не являются статичными.

Когда в символе DEBUG загружен (т.е. отладка в VS), то фактические физические файлы вызываются из MVC View. Однако в режиме Release он вызывает виртуальный файл, который может выглядеть примерно так: /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(), но он всегда возвращает исходные пути к файлам.

Я также открыт для альтернативных предложений по реализации. Благодарю.

ОБНОВЛЕНИЕ: (7/7/14 13:45)

Помимо ответа ниже, я также добавил этот класс реестра Bundles, чтобы сохранить список необходимых статических файлов, чтобы он работал в режиме отладки во всех браузерах. (См. Комментарии ниже)

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

Я ни в коем случае не доволен этим решением. Пожалуйста, сделайте предложения, если вы можете улучшить это.

1 ответ

Решение

Я могу предложить альтернативу из этого поста в блоге создать свой собственный токен.

Таким образом, автор предлагает использовать веб-основы для создания связанного файла, а затем создать вспомогательный инструмент для генерации токена, в данном случае на основе последних измененных даты и времени.

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

Тогда вы можете контролировать токен и можете делать с ним все, что хотите.

Другие вопросы по тегам