2015-10-13 1 views
2

У меня есть приложение Angular.js, и, поскольку это одностраничное приложение, я загружаю некоторые сценарии динамически, в зависимости от пользовательской навигации, поэтому я не Не получишь перегрузки.ASP.NET MVC пакет не будет обновляться, если динамически загружается

Проблема заключается в том, что некоторые из этих сценариев угасаются и минимизируются в пакете ASP.NET MVC, а когда я обновляю исходный скрипт, импортированный пакет никогда не обновляется.

Почему это происходит, и что я могу сделать, чтобы заставить обновление?

ответ

2

Почему это происходит

сверток ASP.NET поставляется с механизмом кэширования. Когда вы добавляете пакет на страницу с помощью Scripts.Render, механизм автоматически помещает строку запроса v в URL-адрес пакета.

@Scripts.Render("~/bundles/commands") 

производит что-то вроде:

<script src="/bundles/commands?v=eiR2xO-xX5H5Jbn3dKjSxW7hNCH9DfgZHqGApCP3ARM1"></script> 

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

Информация о струне v запроса предоставляется here ("Bundle Caching"), но это не очень полезно.

Что я могу сделать

Вы все еще можете загрузить скрипты динамически в комплекте, но вам придется добавить параметр v. Обратите внимание, что это не сработает, если вы попробуете случайно сгенерированный хеш (я попробовал). Благодаря Frison B Alexander, это возможно, используя этот подход:

private static string GetHashByBundlePath(string bundlePath) 
{ 
    BundleContext bundleContext = new BundleContext(new HttpContextWrapper(System.Web.HttpContext.Current), BundleTable.Bundles, bundlePath); 
    Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath); 
    BundleResponse bundleResponse = bundle.GenerateBundleResponse(bundleContext); 
    Type bundleReflection = bundleResponse.GetType(); 
    MethodInfo method = bundleReflection.GetMethod("GetContentHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
    object contentHash = method.Invoke(bundleResponse, null); 
    return contentHash.ToString(); 
} 

Так что вы можете сделать, это: Вернуть расслоение хэш с точки зрения ASP.NET и получить его, когда вам нужно загрузить скрипт.

я мое заявление, я создал объект JS, специфичный для него:

var appBundles = { 
    commands: "/bundles/commands?v=eiR2xO-xX5H5Jbn3dKjSxW7hNCH9DfgZHqGApCP3ARM1" 
}; 

Надеется, что это помогает!

0

У меня возникла проблема с пакетами, которые не обновлялись при загрузке пакетов из одного приложения MVC в другое приложение MVC с использованием GTM (звук перепутался, но на самом деле это имеет смысл в контексте обмена несколькими кодами приложений MVC).

То, что я придумал, это то, что написал Маркос Лима в своем ответе, но сделал еще один шаг.

Я добавил Bundle контроллер с помощью следующего кода:

public class BundleController : Controller 
{ 
    private static string GetHashByBundlePath(string bundlePath) 
    { 
     BundleContext bundleContext = new BundleContext(new HttpContextWrapper(System.Web.HttpContext.Current), BundleTable.Bundles, bundlePath); 
     Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath); 
     BundleResponse bundleResponse = bundle.GenerateBundleResponse(bundleContext); 
     Type bundleReflection = bundleResponse.GetType(); 
     MethodInfo method = bundleReflection.GetMethod("GetContentHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
     object contentHash = method.Invoke(bundleResponse, null); 
     return contentHash.ToString(); 
    } 

    public ActionResult Index(string bundleName) 
    { 
     string bundlePath = "~/bundles/" + bundleName; 
     var hash = GetHashByBundlePath(bundlePath); 
     return RedirectPermanent(bundlePath + "?v=" + hash); 
    } 
} 

Затем я добавил этот маршрут:

routes.MapRoute(
    name: "Bundle", 
    url: "Bundle/{bundleName}", 
    defaults: new { controller = "Bundle", action = "Index" } 
); 

Конечным результатом является то, что я прошу пучки через контроллер, но поскольку я перенаправляю 301, действие Index запускается только один раз для каждого пользователя, и оно возвращает текущую версию пакета, и затем пакет затем отправляется из кеша браузера. Когда я действительно обновляю пакет, я добавляю некоторый параметр запроса в url запроса (в GTM), и теперь все пользователи получают обновленный комплект.

Конечно, я предполагаю, что пучки размещены в пути ~/bundles/, но это должно быть достаточно легко изменить, если вы размещены в другом месте. На самом деле маршрут не нужен.