Объединение не работает для сопоставленного виртуального каталога

У нас есть сайт, на котором CSS и JavaScript объединены в каталоги /Content/ и /Scripts/ соответственно. Оба они также являются сопоставленными целями виртуальных каталогов в отдельном домене, который используется для статических ресурсов (поэтому файлы cookie не обслуживаются).

Проблема заключается в том, что в нашей производственной среде, где для параметра compilation -> debug установлено значение false (поэтому включено связывание и минимизация), относительные URL-адреса работают нормально и обслуживаются из системы связывания, но URL-адреса статического домена (с использованием виртуальных каталогов, указывающих на то же место) дают HTTP 404 errors.

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

Вот как выглядит текущий порядок обработки от IIS:

  1. Получить входящий запрос на (связанный) ресурс, например. [static domain]/Content/all.css
  2. Запустите любые обработчики HTTP, например. объединение, если доступно (в данном случае статического домена нет)
  3. Следуйте виртуальному каталогу и обслуживайте ресурс, если он доступен, т.е. ищет ([main domain]/Content/all.css)

Поскольку этот файл на самом деле не существует в файловой системе, возникает HTTP 404. В идеале шаг 2 должен выполняться после шага 3.

Большое спасибо.


person d_mcg    schedule 29.01.2013    source источник


Ответы (2)


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

В итоге работает следующее:

  • Пусть статический домен указывает на отдельную корневую папку в файловой системе.
  • Держите виртуальные каталоги на статическом сайте (/Content/ и /Scripts/), указывая на соответствующие им места на основном сайте.
  • Поскольку мы используем средство перезаписи URL-адресов Helicon для очистки кеша, создайте базовый файл .htaccess с тем же правилом, что и на основном сайте; поместите это в корень статического сайта.
  • Скопируйте файл global.asax с основного сайта в корень статического сайта. Это не может быть коротким путем.
  • Copy the contents of the /bin/ folder from the main website into the static site.
    • A virtual directory in IIS pointing to the /bin/ folder on the main website will NOT work.
    • Создать ярлык в файловой системе к папке /bin/ на основном сайте тоже не получится.
  • В IIS убедитесь, что статический сайт использует собственный пул приложений и что он настроен для .NET 4.0, режим интегрированного конвейера. Это сделано для того, чтобы связка MVC 4 работала.
  • Создайте базовую версию web.config с добавлением UrlRoutingModule.

Это наш web.config для статического сайта:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <customErrors mode="Off">
        </customErrors>
        <sessionState mode="Off" />
        <pages enableSessionState="false" enableViewState="false" enableViewStateMac="false" renderAllHiddenFieldsAtTopOfForm="false" />
    </system.web>
    <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <modules runAllManagedModulesForAllRequests="true">
            <remove name="ScriptModule" />
            <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </modules>
        <urlCompression doStaticCompression="true" doDynamicCompression="true" />
        <security>
            <requestFiltering allowDoubleEscaping="True" />
        </security>
        <tracing>
            <traceFailedRequests>
                <add path="*">
                    <traceAreas>
                        <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
                    </traceAreas>
                    <failureDefinitions timeTaken="00:00:00" statusCodes="200" />
                </add>
            </traceFailedRequests>
        </tracing>
        <!-- Cache static content for a month, only enable on UAT or Live -->
        <staticContent>
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00"/>
        </staticContent>
    </system.webServer>
</configuration>

Основная идея заключается в том, что для связывания требуется, чтобы ASP.NET MVC4 был включен и работал на статическом сайте, поскольку связывание оценивается IIS до того, как будут рассмотрены виртуальные каталоги (и, похоже, нет способа изменить это).

person d_mcg    schedule 04.02.2013

В файлах css создайте URL-адреса с относительными путями, например:

div.loader {
    background-image: url("../grail/images/loader.gif");
}

В файлах js используйте скрытый файл с мастер-страницы:

@Html.Hidden("HiddenCurrentUrl",  Url.Content("~"))

В бандлах вместо CssRewriteUrlTransform используйте свой пользовательский IItemTransform

public class VirtualCssRewriteUrlTransform : IItemTransform
{
    private CssRewriteUrlTransform wrapper;

    public VirtualCssRewriteUrlTransform ()
    {
        this.wrapper = new CssRewriteUrlTransform();
    }

    public string Process(string includedVirtualPath, string input)
    {
        var result = this.wrapper.Process(includedVirtualPath, input);
        // if virtual directory exists
        if (HttpRuntime.AppDomainAppVirtualPath != "/")
        {
            result = result.Replace(@"url(/", @"url(" + HttpRuntime.AppDomainAppVirtualPath + @"/");
        }

        return result;
    }
}
person Marek Jankowski    schedule 13.02.2014