Подтвердить что ты не робот

MVC4 - Связывание не работает, если для оптимизаций установлено значение true

Интересно, что я здесь не делаю. Я использую ASP.NET С# MVC4, и я хочу использовать новую функцию оптимизации css/js.

Вот моя часть HTML

@Styles.Render("~/content/css")

Вот моя часть BunduleConfig.cs

bundles.Add(new StyleBundle("~/content/css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

// BundleTable.EnableOptimizations = true;

Выход (работает):

<link href="/content/css/reset.css" rel="stylesheet"/>
<link href="/content/css/bla.css" rel="stylesheet"/>

Однако, когда я раскомментирую BundleTable.EnableOptimizations = true; вывод html, это выглядит как

<link href="/content/css?v=5LoJebKvQJIN-fKjKYCg_ccvmBC_LF91jBasIpwtUcY1" rel="stylesheet"/>

И это, конечно, 404. Я понятия не имею, где я сделал что-то не так, пожалуйста, помогите, впервые работая с MVC4.

4b9b3361

Ответ 1

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

MVC создает виртуальный файл из вашего пакета и обслуживает его по пути, указанному вами как путь к пакету.

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

Пример:

Если на вашем сайте есть папка с именем /content/css, сделайте свой css-пакет следующим образом:

В BundleConfig.cs:

bundles.Add(new StyleBundle("~/content/css/AllMyCss.css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

И на странице:

@Styles.Render("~/content/css/AllMyCss.css")

Обратите внимание, что это предполагает, что у вас нет файла с именем AllMyCss.css в вашей папке css.

Ответ 2

Я не уверен, что это веб-оптимизация, или WebGrease, которая настолько придирчива, но одна (или и то и другое) из них, и вам нужно быть предельно осторожным.

Прежде всего, в коде нет ничего плохого:

bundles.Add(new StyleBundle("~/content/css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

Фактически это именно то, что делает Microsoft. Основная причина, по которой они не используют ~/bundles для css, заключается в том, что относительные пути закручиваются для изображений. Подумайте о том, как ваш браузер видит пакет - точно так же, как он видит какой-либо другой URL-адрес, и все правила нормального пути все еще применяются в отношении относительных путей. Представьте, что у вашего css был путь изображения к ../images/bullet.png. Если вы использовали ~/bundles, браузер будет искать в каталоге выше bundles, который фактически не существует. Вероятно, это будет выглядеть в ~/images, где вы, вероятно, имеете его в ~/content/images.

Я нашел пару вещей, которые могут действительно сломать его и вызвать 404 ошибки:

  • FYI: моя структура каталогов Content/CSS, которая содержит папку images для изображений CSS.
  • У меня есть EnableOptimizations=true для принудительного использования пакетов при тестировании
  • Первое, что вам нужно сделать, это "View Source" и просто нажать на ссылки css, чтобы увидеть, работают ли они.

Скажем, мы разрабатываем сайт о кошках. У вас может быть этот

 @Styles.Render("~/Content/css/cats.css")    // dont do this - see below why

 bundles.Add(new StyleBundle("~/content/css/cats.css").Include(
                    "~/content/css/reset.css",
                    "~/content/css/bla.css"));

Это создает ссылку CSS для этого пути в вашем HTML:

/Content/css/cats.css?v=JMoJspikowDah2auGQBfQAWj1OShXxqAlXxhv_ZFVfQ1

Однако это даст 404, потому что я поставил расширение .css и IIS (я думаю) запутался.

Если я изменю его на это, тогда он отлично работает:

 @Styles.Render("~/Content/css/cats")

 bundles.Add(new StyleBundle("~/content/css/cats").Include(
                    "~/content/css/reset.css",
                    "~/content/css/bla.css"));

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

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

если у вас есть каталог или файл css (вряд ли у вас будет файл с именем css без расширения) в вашем каталоге Content.

Дополнительный трюк заключается в том, что вам нужно убедиться, что ваш сгенерированный HTML имеет номер версии

<link href="/Content/css/cats?v=6GDW6wAXIN5DJCxVtIkkxLGpojoP-tBQiKgBTQMSlWw1" rel="stylesheet"/>

Если это не так и выглядит так, то у вас, вероятно, нет точного соответствия имени пакета между вашей таблицей Bundle и в вашем файле cshtml.

<link href="/Content/css/cats" rel="stylesheet"/>

Ответ 3

Не забудьте убедиться, что существует пакет HttpModule.

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

Это ужалило меня в первый раз. Не уверен, что необходимая конфигурация должна быть добавлена ​​пакетом NuGet, но это было не в моем случае.

Ответ 4

Это выглядит правильно для меня. Когда оптимизация включена, вы будете иметь только один ref, и это будет имя, указанное вами в вашем StyleBundle (/content/css). В режиме отладки (или более конкретно с debug = false в вашей веб-конфигурации) вы получите не оптимизированные файлы как обычно. Если вы посмотрите, вы увидите, что они просто текст, когда вы их набрали. Однако при включении оптимизаций (обычно, когда вы запускаете в режиме деблокирования) вместо этого вы получите wierd look URL.

Если вы посмотрите на результат этого, он будет уменьшен. Строка запроса? V = 5KLoJ.... основана на хэше, взятом из файлов в комплекте. Это так, что ссылка может быть безопасно кэширована HTTP столько, сколько вы хотите. Навсегда, если вы хотите, но я думаю, что по умолчанию - год. Однако, если вы измените какую-либо из своих таблиц стилей, она создаст новый хеш и "перехватит кеш", чтобы вы получили новую копию в браузере.

Сказав все это, я не уверен, почему вы получаете 404. Я подозреваю, что это связано с вашей конфигурацией маршрутизации или с настройкой IIS. Вы работаете в Visual Studio с помощью IISExpress?

Ответ 5

Я просто решил аналогичную проблему. Проблема заключалась в следующем: я установил "выбрано" через NuGet. И в классе BundleConfig строка, содержащая файл CSS, выглядела так:

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",)); 
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/chosen.css"));

В некоторых случаях, когда в этом классе я имел следующую строку:

BundleTable.EnableOptimizations = true;

Исправление состояло в том, чтобы объединить 2 bundles.Add() следующим образом:

bundles.Add(new StyleBundle("~/Content/css").Include(
                            "~/Content/site.css", 
                            "~/Content/chosen.css"
                        ));

И это исправило это для меня.

Ответ 6

Это также может быть связано с тем, что по какой-то причине вы не развернули пакет bundleconfig.json на сервере.