Как заставить BundleCollection сбрасывать кэшированные пакеты сценариев в MVC4C#

Место общения программистов C#
Anonymous
Как заставить BundleCollection сбрасывать кэшированные пакеты сценариев в MVC4

Сообщение Anonymous »

... или как я научился не беспокоиться и просто писать код для совершенно недокументированных API от Microsoft. Есть ли актуальная документация официального выпуска System.Web.Optimization? «Потому что я точно не могу их найти, нет XML-документов, и все сообщения в блогах относятся к API RC, который существенно отличается. Anyhoo..

Я пишу код для автоматического разрешения зависимостей JavaScript и создаю пакеты на лету из этих зависимостей. Все работает отлично, за исключением того, что если вы редактируете скрипты или иным образом вносите изменения, которые могут повлиять на пакет, без перезапуска приложения, изменения не будут отражены. Поэтому я добавил возможность отключить кэширование зависимостей для использования в разработке.

Однако, очевидно, BundleTables кэширует URL-адрес даже если коллекция пакетов изменилась. Например, в моем собственном коде, когда я хочу воссоздать пакет, я делаю что-то вроде этого:

Код: Выделить всё

// remove an existing bundle
BundleTable.Bundles.Remove(BundleTable.Bundles.GetBundleFor(bundleAlias));

// recreate it.
var bundle = new ScriptBundle(bundleAlias);

// dependencies is a collection of objects representing scripts,
// this creates a new bundle from that list.

foreach (var item in dependencies)
{
bundle.Include(item.Path);
}

// add the new bundle to the collection

BundleTable.Bundles.Add(bundle);

// bundleAlias is the same alias used previously to create the bundle,
// like "~/mybundle1"

var bundleUrl = BundleTable.Bundles.ResolveBundleUrl(bundleAlias);

// returns something like "/mybundle1?v=hzBkDmqVAC8R_Nme4OYZ5qoq5fLBIhAGguKa28lYLfQ1"
Каждый раз, когда я удаляю и воссоздаю пакет с тем же псевдонимом, абсолютно ничего не происходит: BundleUrl, возвращаемый из ResolveBundleUrl, тот же, что и до удаления и повторного создания пакета. Под «тот же» я подразумеваю, что хеш контента не изменяется и отражает новое содержимое пакета.

редактировать... на самом деле все гораздо хуже. Сам пакет каким-то образом кэшируется за пределами коллекции Bundles. Если я просто сгенерирую свой собственный случайный хэш, чтобы браузер не кэшировал сценарий, ASP.NET вернет старый сценарий. Итак, очевидно, что удаление пакета из BundleTable.Bundles на самом деле ничего не дает.

Я могу просто изменить псевдоним, чтобы обойти эту проблему, и это нормально для разработки, но мне не нравится эта идея, поскольку это означает, что мне придется либо отказаться от псевдонимов после каждой загрузки страницы, либо иметь BundleCollection, размер которой увеличивается при каждой загрузке страницы. Если бы вы оставили это включенным в производственной среде, это было бы катастрофой.

Поэтому кажется, что когда скрипт обслуживается, он кэшируется независимо от фактического объекта BundleTables.Bundles. Таким образом, если вы повторно используете URL-адрес, даже если вы удалили пакет, на который он ссылался, прежде чем повторно использовать его, он отвечает всем, что находится в его кеше, а изменение объекта Bundles не очищает кеш - поэтому будут использоваться только новые элементы (или, скорее, новые элементы с другим именем).

Поведение кажется странным... удаление чего-либо из коллекции должно удалять его из кеша. Но это не так. Должен быть способ очистить этот кеш и заставить его использовать текущее содержимое BundleCollection вместо того, что было кэшировано при первом доступе к этому пакету.

Есть идеи, как бы это сделать?

Есть метод ResetAll, цель которого неизвестна, но он все равно просто ломает вещи, так что это не так.>

Вернуться в «C#»