Почему мой CSS-пакет не работает с развернутым bin-приложением MVC4?

Я развернул приложение MVC4 для своего хостинг-провайдера, основываясь на приведенном здесь совете и одном или двух исправлениях на лету, но наиболее очевидная проблема заключается в том, что пакет для css не работает. Когда я заменяю ссылку на комплект явными ссылками на файл, мой css снова работает.

Я использую стандартный шаблон проекта MVC4 RTM от VS2012. Поставщик использует IIS 7.5 и ASP.NET 4, и моя предыдущая версия того же приложения MVC3 работала нормально. Я предполагаю, что я получил зависимость где-то слишком низкой версии, и это также может способствовать моей проблеме ссылки действия на основе области.

Технические симптомы:

Линия @Styles.Render("~/Content/css") отображается как <link href="/Content/css?v=" rel="stylesheet"/>

19 ответов

Решение

Связывание CSS и скриптов должно работать независимо от того, работает ли.NET 4.0 или 4.5. Я использую.NET 4.0, и он прекрасно работает для меня. Однако, чтобы заставить работать минимизацию и связывание, ваш web.config должен быть настроен так, чтобы он не работал в режиме отладки.

<compilation debug="false" targetFramework="4.0">

Возьмите этот пакет для примера пользовательского интерфейса jQuery в файле _Layout.cshtml.

@Styles.Render("~/Content/themes/base/css")

Если я бегу с debug="true" Я получаю следующий HTML.

<link href="/Content/themes/base/jquery.ui.core.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.resizable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.selectable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.accordion.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.autocomplete.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.button.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.dialog.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.slider.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.tabs.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.datepicker.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.progressbar.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.theme.css" rel="stylesheet"/>

Но если я бегу с debug="false", Я получу это вместо этого.

<link href="/Content/themes/base/css?v=myqT7npwmF2ABsuSaHqt8SCvK8UFWpRv7T4M8r3kiK01" rel="stylesheet"/>

Это функция, которая позволяет легко отлаживать проблемы с вашими файлами Script и CSS. Я использую MVC4 RTM.

Если вы считаете, что это может быть проблема с зависимостью MVC, я бы порекомендовал зайти в Nuget и удалить все ваши пакеты, связанные с MVC, а затем найти Microsoft.AspNet.Mvc упаковать и установить его. Я использую самую последнюю версию, и она выйдет как v.4.0.20710.0. Это должно захватить все зависимости, которые вам нужны.

Также, если вы использовали MVC3 и теперь пытаетесь использовать MVC4, вам нужно зайти в ваш web.config (ы) и обновить их ссылки, чтобы они указывали на версию MVC 4.0. Если вы не уверены, вы всегда можете создать свежее приложение MVC4 и скопировать оттуда файл web.config. Не забывайте web.config в ваших папках Views/Areas, если вы это делаете.

ОБНОВЛЕНИЕ: я обнаружил, что вам нужно иметь пакет Nuget Microsoft.AspNet.Web.Optimization установлен в вашем проекте. Он включен по умолчанию в приложение MVC4 RTM независимо от того, указана ли целевая среда как 4.5 или 4.0. Это пространство имен, в которое включены классы связывания, и, по-видимому, не зависит от платформы. Я развернул сервер, на котором не установлено 4.5, и он все еще работает, как и ожидалось. Просто убедитесь, что DLL развернута вместе с остальной частью вашего приложения.

ОБНОВЛЕНИЕ 4/4/2013:

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

Рекомендуемый способ исправить это для повышения производительности - удалить .js или .css из имени вашего пакета.

Так /bundle/myscripts.js становится / bundle / myscripts

В качестве альтернативы вы можете изменить ваш web.config в разделе system.webServer, чтобы выполнить эти запросы через BundleModule (который был моим первоначальным ответом)

<modules runAllManagedModulesForAllRequests="true">
  <remove name="BundleModule" />
  <add name="BundleModule" type="System.Web.Optimization.BundleModule" />
</modules>

Редактировать: я также заметил, что если имя оканчивается на "css" (без точки), это тоже проблема. Мне пришлось изменить имя пакета с "DataTablesCSS" на "DataTablesStyles", чтобы исправить мою проблему.

Просто чтобы уточнить несколько вещей, System.Web.Optimization (aka Bundling / Minification) будет работать против 4.0. Это не зависит от чего-либо в 4.5, поэтому там не должно быть проблем.

Если связывание скриптов работает, и это единственная проблема с CSS, возможно, проблема связана с относительными URL-адресами?

Сначала я посмотрю на визуализированную страницу и выясню, есть ли у вас ссылки на CSS-пакет, то есть что-то вроде:

<link href="/app/Content/css?v=oI5uNwN5NWmYrn8EXEybCI" rel="stylesheet"/>

Если да, то пакетирование работает, но что-то внутри вашего CSS-пакета испорчено. Обычно это происходит из-за того, что относительные URL-адреса внутри вашего CSS-пакета неверны, т. Е. Если ваши изображения находятся в ~/Content, но вы называете свой пакет ~/bundles/cssбраузер будет некорректно искать изображения под ~/bundles,

Кроме того, поведение по умолчанию отключает связывание и минификацию, когда debug=true, Итак, если вы хотите, чтобы оптимизация была включена, даже когда debug=true, вам нужно будет заставить:

BundleTable.EnableOptimizations = true

Обновлено: с новой информацией, которая v="", это означает, что пакет был пуст, вы должны убедиться, что вы добавляете файлы в пакет правильно и он их нашел. Как вы включаете файлы в комплект?

Опуская runAllManagedModulesForAllRequests="true" также работал для меня. Добавьте следующую конфигурацию в web.config:

<modules>
  <remove name="BundleModule" />
  <add name="BundleModule" type="System.Web.Optimization.BundleModule" />
</modules>

runAllManagedModulesForAllRequests приведет к снижению производительности на вашем сайте, если не используется надлежащим образом. Проверьте эту статью.

Еще одна вещь, которую следует учитывать, - ссылки не могут иметь одинаковые имена. Например, если у вас есть JQuery UI в libraries каталог, и связать его файл JavaScript следующим образом:

bundles.Add(new ScriptBundle("~/libraries").Include("~/libraries/jquery-ui/jqyery-ui.js"));

а затем попробуйте связать свои CSS-файлы следующим образом:

bundles.Add(new StyleBundle("~/libraries").Include("~/libraries/jquery-ui/jqyery-ui.css"));
...

это не удастся. У них должны быть уникальные имена. Так что-то вроде ScriptBundle("~/libraries/js")... а также ScriptBundle("~/libraries/css")... или что угодно.

Один из моих файлов CSS имел символ "_" в имени файла, что вызывало проблемы.

Переименован в your_style.css в yourstyle.css

В качестве дополнения к существующим ответам, ни один из которых не работал для меня, я нашел свое решение ЗДЕСЬ:

https://bundletransformer.codeplex.com/discussions/429707

Решение было

  1. щелкните правой кнопкой мыши файлы.less в visual studio
  2. Выберите свойства
  3. Отметить Build Action как Content
  4. передислоцировать

Мне НЕ нужно было удалять обработчики без расширений (как можно найти в других решениях в Интернете)

Я не должен был добавлять <add name="BundleModule" type="System.Web.Optimization.BundleModule" /> Настройка web.config.

Надеюсь это поможет!

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

Следующее проверяет, существует ли BundleModule в web.config и загружается, и устанавливает EnableOptimizations в зависимости от его существования.

Таким образом, независимо от того, доступен он или нет, ссылки на css/js будут работать нормально. Другими словами:

  • Если BundleModule доступен, бандлинг / оптимизация будут включены.

  • Если BundleModule недоступен, бандлинг / оптимизация будут отключены, и вместо них будут автоматически использованы полные ссылки.

Код:

public static void RegisterBundles(BundleCollection bundles)
{
   // bundeling code here
   // ...
   // bundeling code here

   bool bundelingModuleIsAvailable = false;
   try { 
       bundelingModuleIsAvailable = HttpContext.Current.ApplicationInstance.Modules.AllKeys.Contains("BundleModule"); 
   }
   catch { }
   if (!bundelingModuleIsAvailable)
       System.Diagnostics.Debug.WriteLine("WARNING : optimization bundle is not added to Web.config!");

   BundleTable.EnableOptimizations = bundelingModuleIsAvailable && !Debug_CheckIsRunning();
   //Debug_CheckIsRunning is optional, incase you want to disable optimization when debugging yourself
   BundleTable.EnableOptimizations = true;
}

private bool Debug_CheckIsRunning()
{//Check if debug is running
    string moduleName = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName;
    return (moduleName.Contains("iisexpress.exe") || moduleName.Contains(".vshost") || moduleName.Contains("vstest.executionengine") || moduleName.Contains("WebDev.WebServer"));
    }

Я столкнулся с той же проблемой с CSS в реальной среде. Я следовал всем советам здесь и исследовал, как комплектация работает за кулисами. Это привело меня к просьбе очистить кеш.Net (у меня не было доступа к серверам приложений), что привело к тому, что пакет начал работать на серверах приложений. Однако при доступе к сайту через балансировщик нагрузки с настроенным CDN, хотя идентификатор пакета был обновлен в URL, пакет содержал старый CSS. Просто сброс CDN решил проблему.

Я надеюсь, что это поможет кому-то еще, кто может столкнуться с этим

В Visual Studio 2015 я обнаружил, что проблема была вызвана ссылкой на версию.min файла javascript в BundleConfig, когда в файле web.config установлено значение debug = true.

Например, с помощью jquery, указав в BundleConfig следующее:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.min.js"));

приводил к тому, что jquery вообще не загружался правильно, когда в файле web.config был задан параметр debug = true.

Ссылка на неунифицированную версию:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js"));

исправляет проблему.

Установка debug = false также исправляет проблему, но, конечно, это не совсем полезно.

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

Я столкнулся с этой проблемой при развертывании кода на веб-сайтах Azure. это сработало, когда я развернул сборку с visualstudio.com, и не сработал, когда я попытался опубликовать сборку из visual studio 2013. Основной проблемой была минимизация CSS. Я полностью согласен с 1-м ответом на этот вопрос. но подумал о том, чтобы поделиться решением, которое сработало для меня, может быть, оно поможет вам исправить это.

в основном, когда мы разворачиваемся через VSO, он генерирует файлы минимизации для css, js, нажимая на system.web.Optimization, но когда мы публикуем сборку из VS 2013, мы должны позаботиться о следующем. 1. Удостоверьтесь, что структура папок и ваше соглашение о присвоении имен должны отличаться. что-то вроде этого.

bundles.Add(new StyleBundle("~/Content/materialize/mcss").Include(
                  "~/Content//materialize/css/materialize.css"));

2. добавьте внизу вашего определения комплекта

public static void RegisterBundles(BundleCollection bundles)
{
  bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
             "~/Scripts/jquery-{version}.js"));

   // Code removed for clarity.
   BundleTable.EnableOptimizations = true;
}

3. убедитесь, что добавили debug false в web.config (когда вы запускаете локальную отладку, VS2013 выдаст всплывающее окно с сообщением о том, что вам необходимо убедиться, что вы вернули его перед развертыванием в prod. Это само по себе многое объясняет.

<system.web>
  <compilation debug="true" />
  <!-- Lines removed for clarity. -->
</system.web>

Вам нужно добавить этот код в общий вид

 @*@Scripts.Render("~/bundles/plugins")*@
    <script src="/Content/plugins/jQuery/jQuery-2.1.4.min.js"></script>
    <!-- jQuery UI 1.11.4 -->
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    <!-- Kendo JS -->
    <script src="/Content/kendo/js/kendo.all.min.js" type="text/javascript"></script>
    <script src="/Content/kendo/js/kendo.web.min.js" type="text/javascript"></script>
    <script src="/Content/kendo/js/kendo.aspnetmvc.min.js"></script>
    <!-- Bootstrap 3.3.5 -->
    <script src="/Content/bootstrap/js/bootstrap.min.js"></script>
    <!-- Morris.js charts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
    <script src="/Content/plugins/morris/morris.min.js"></script>
    <!-- Sparkline -->
    <script src="/Content/plugins/sparkline/jquery.sparkline.min.js"></script>
    <!-- jvectormap -->
    <script src="/Content/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script>
    <script src="/Content/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script>
    <!-- jQuery Knob Chart -->
    <script src="/Content/plugins/knob/jquery.knob.js"></script>
    <!-- daterangepicker -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
    <script src="/Content/plugins/daterangepicker/daterangepicker.js"></script>
    <!-- datepicker -->
    <script src="/Content/plugins/datepicker/bootstrap-datepicker.js"></script>
    <!-- Bootstrap WYSIHTML5 -->
    <script src="/Content/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script>
    <!-- Slimscroll -->
    <script src="/Content/plugins/slimScroll/jquery.slimscroll.min.js"></script>
    <!-- FastClick -->
    <script src="/Content/plugins/fastclick/fastclick.min.js"></script>
    <!-- AdminLTE App -->
    <script src="/Content/dist/js/app.min.js"></script>
    <!-- AdminLTE for demo purposes -->
    <script src="/Content/dist/js/demo.js"></script>
    <!-- Common -->
    <script src="/Scripts/common/common.js"></script>
    <!-- Render Sections -->
    @RenderSection("scripts", required: false)
    @RenderSection("HeaderSection", required: false)

У меня была эта проблема при добавлении некоторых пакетов из Nuget и я забыл сделать обновление

Поэтому сначала сделайте обновление всех пакетов, установленных в проекте.

Update-Package

В Global.asax.cs добавьте следующее

BundleTable.EnableOptimizations = true;

Имена css должны быть последовательными

Имена jqueryUI css не являются "jquery.ui.XXX" в папке Contents/themes/base.

так и должно быть:

неправильно:

            bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                                    "~/Content/themes/base/jquery.ui.core.css",
                                    "~/Content/themes/base/jquery.ui.resizable.css",
                                    "~/Content/themes/base/jquery.ui.selectable.css",
                                    "~/Content/themes/base/jquery.ui.accordion.css",
                                    "~/Content/themes/base/jquery.ui.autocomplete.css",
                                    "~/Content/themes/base/jquery.ui.button.css",
                                    "~/Content/themes/base/jquery.ui.dialog.css",
                                    "~/Content/themes/base/jquery.ui.slider.css",
                                    "~/Content/themes/base/jquery.ui.tabs.css",
                                    "~/Content/themes/base/jquery.ui.datepicker.css",
                                    "~/Content/themes/base/jquery.ui.progressbar.css",
                                    "~/Content/themes/base/jquery.ui.theme.css"));

правильный:

            bundles.Add(new StyleBundle("~/Bundles/themes/base/css").Include(
                                    "~/Content/themes/base/core.css",
                                    "~/Content/themes/base/resizable.css",
                                    "~/Content/themes/base/selectable.css",
                                    "~/Content/themes/base/accordion.css",
                                    "~/Content/themes/base/autocomplete.css",
                                    "~/Content/themes/base/button.css",
                                    "~/Content/themes/base/dialog.css",
                                    "~/Content/themes/base/slider.css",
                                    "~/Content/themes/base/tabs.css",
                                    "~/Content/themes/base/datepicker.css",
                                    "~/Content/themes/base/progressbar.css",
                                    "~/Content/themes/base/theme.css"));

Я пробовал в MVC5 и работал успешно.

Попробуй это:

    @System.Web.Optimization.Styles.Render("~/Content/css")
    @System.Web.Optimization.Scripts.Render("~/bundles/modernizr")

Это сработало для меня. Я все еще учусь, и я еще не понял, почему это происходит

Просто для истории:

Убедитесь, что все упомянутые файлы less/css в комплекте имеют Build Action = "Content".

Нет ошибки, если на конечном сервере отсутствуют файлы из пакета.

Чтобы добавить полезную информацию к беседе, я обнаружил 404 ошибки для моих пакетов в развертывании (это было хорошо в локальной среде разработчика).

Для имен пакетов я включил номера версий, например:

bundles.Add(new ScriptBundle("~/bundles/jquerymobile.1.4.3").Include(
...
);

По прихоти я удалил все точки и все снова волшебным образом заработало:

bundles.Add(new ScriptBundle("~/bundles/jquerymobile143").Include(
...
);

Надеюсь, что это поможет кому-то сэкономить время и разочарование.

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

Это решило мою проблему. Я добавил эти строки в _layout.cshtml

@*@Scripts.Render("~/bundles/plugins")*@
<script src="/Content/plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- jQuery UI 1.11.4 -->
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<!-- Kendo JS -->
<script src="/Content/kendo/js/kendo.all.min.js" type="text/javascript"></script>
<script src="/Content/kendo/js/kendo.web.min.js" type="text/javascript"></script>
<script src="/Content/kendo/js/kendo.aspnetmvc.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="/Content/bootstrap/js/bootstrap.min.js"></script>
<!-- Morris.js charts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="/Content/plugins/morris/morris.min.js"></script>
<!-- Sparkline -->
<script src="/Content/plugins/sparkline/jquery.sparkline.min.js"></script>
<!-- jvectormap -->
<script src="/Content/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script>
<script src="/Content/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script>
<!-- jQuery Knob Chart -->
<script src="/Content/plugins/knob/jquery.knob.js"></script>
<!-- daterangepicker -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<script src="/Content/plugins/daterangepicker/daterangepicker.js"></script>
<!-- datepicker -->
<script src="/Content/plugins/datepicker/bootstrap-datepicker.js"></script>
<!-- Bootstrap WYSIHTML5 -->
<script src="/Content/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script>
<!-- Slimscroll -->
<script src="/Content/plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="/Content/plugins/fastclick/fastclick.min.js"></script>
<!-- AdminLTE App -->
<script src="/Content/dist/js/app.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="/Content/dist/js/demo.js"></script>
<!-- Common -->
<script src="/Scripts/common/common.js"></script>
<!-- Render Sections -->

У меня такая же проблема. я просто конвертирую

@Styles.Render("~/Content/css")
and @Scripts.Render("~/bundles/modernizr") to 
    @Styles.Render("/Content/css")
    @Scripts.Render("/bundles/modernizr")

и это сработало. просто не забудьте конвертировать

   @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
to 
    @Scripts.Render("/bundles/jquery")
    @Scripts.Render("/bundles/bootstrap")

хорошо провести время

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