捆绑不适用于映射的虚拟目录

时间:2013-01-29 22:57:56

标签: iis-7 asp.net-mvc-4 bundle virtual-directory asp.net-optimization

我们有一个网站,其中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
  4. 由于文件系统上并不存在此文件,因此会引发HTTP 404。理想情况下,步骤 2 应在步骤 3 之后运行。

    非常感谢。

2 个答案:

答案 0 :(得分:2)

我做了一些实验并设法解决了它。 工作的是将静态站点的根目录指向主网站的同一根,因为web.config文件是共享的 - 任何更改(即禁用会话状态)都是静态网站也适用于主网站。

最后,有效的是:

  • 让静态域指向文件系统上的单独根文件夹。
  • 保持静态网站(/Content//Scripts/)上的虚拟目录指向主网站上的相应位置。
  • 由于我们使用Helicon的URL重写器进行缓存清除,因此请使用与主站点中使用的规则相同的规则创建一个简单的.htaccess文件。把它放在静态站点的根目录中。
  • global.asax文件从主网站复制到静态网站的根目录中。这不是捷径。
  • /bin/文件夹的内容从主网站复制到静态网站。
    • IIS中指向主网站上/bin/文件夹的虚拟目录将无效。
    • 在文件系统中创建主网站上/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会对捆绑进行评估(并且似乎没有办法解决此问题)

答案 1 :(得分:1)

在css文件中创建具有相对路径的URL,例如:

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

在js文件中使用来自母版页的隐藏文件:

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

在bundle而不是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;
    }
}