Merge does not work for mapped virtual directory

We have a site where CSS and JavaScript are embedded in directories /Content/

and /Scripts/

respectively. They both also map the targets of virtual directories in a separate domain that is used for static resources (so no cookies are served).

The problem is that in our production environment, where it is compilation -> debug

set to false (which is why merging and minification is enabled), relative urls work fine and become serviced from the linking system, but domain static urls (using virtual directories pointing to same place) give HTTP 404 errors

.

Is there a way to configure IIS to let the package work for the contents of this virtual directory? I have visions of creating a separate project for an MVC project for a static domain so that it recognizes binding, but would like to see if there is a better solution.

This is the current processing order from IIS:

  • Get an incoming request for a (linked) resource eg. [static domain]/Content/all.css

  • Run any HTTP handlers, eg. bind if available (no static domain in this case)
  • Follow the virtual directory and serve the resource if available, i.e. looking for ([main domain]/Content/all.css

    )

Since this file doesn't really exist on the filesystem, a HTTP 404

. Ideally, step 2 should be done after step 3 .

Many thanks.

+3


source to share


2 answers


I experimented a bit and was able to solve it. What doesn't work is pointing the root of the static site to the same root of the main website as the shared files web.config

- any change (i.e., disconnecting session state) made on the static site also applies to the main site.

In the end what works:

  • Ask the static domain to point to a separate root folder on the file system.
  • Store the virtual directories on a static website ( /Content/

    and /Scripts/

    ), pointing to the appropriate location on the main site.
  • Since we are using Helicon URL-rewriter to iterate over the cache, create a barebones file .htaccess

    with the same rule as on the main site; put this in the root of your static site.
  • Copy the file global.asax

    from the main website to the root of the static site. It cannot be a shortcut.
  • Copy the contents of the folder /bin/

    from the main website to the static site.
    • A virtual directory in IIS pointing to a folder /bin/

      on the main website will NOT work.
    • Creating a shortcut on the file system to a folder /bin/

      on the main website will also not work.
  • In IIS, make sure the static site uses its own application pool and is configured for .NET 4.0, Integrated protocol mode. This is the way that MVC 4 merge will work.
  • Create bare bones web.config

    with added UrlRoutingModule

    .


This is ours web.config

for a static site:

<?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>

      

The basic idea is that binding requires ASP.NET MVC4 to be up and running on a static site, since binding is evaluated by IIS before virtual directories are considered (and there seems to be no way to reverse this).

+2


source


URLs with relative paths are generated in css files, for example:

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

      

In js files use hidden file from main page:



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

      

In bundles, instead of CssRewriteUrlTransform use your custom 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;
    }
}

      

0


source







All Articles