Recently, I worked on a project, where we wanted to use the ASP.NET bundling. After we implemented the bundling and minification and integrated it in our site, the requests for the bundles (CSS und JS) returned a 404 status code. Using the Chrome Developer Tools I could see, that that the response contained the requested JS / CSS. But sadly Chrome (and Firefox) ignored the content, because it was returned with a 404 status code.

Finding the bug

It took me quite some time to figure out, what the problem was. I knew, that we are using the ASP.NET bundling in other projects as well. I checked some of these and all of the bundle requests in those projects returned a status code 200.

After some time, we figured out, that the 404 status code was set by a custom pipeline processor, which handled the "Item Not Found" scenario. But why was the bundle-request executing Sitecore pipeline? The other projects contained the exact same pipeline processor but did not return a 404 status code.

So what do you do when you have such a subtle difference between two projects? Correct, compare the /sitecore/admin/ShowConfig.aspx output. A quick search for "bundle" brought the answer.

The reason

It turned out, that, unlike the other projects, this project had disabled the entire FXM configuration. The FXM contains a pipeline processor called Sitecore.FXM.Pipelines.HttpRequest.IgnoreBundleEntries which is used at the start of the "httpRequestBegin" and "httpRequestEnd" pipelines.  As the name suggests, it aborts the pipeline, if the request is targeted at an ASP.NET bundle.

This processor looks something like this:

public override void Process(HttpRequestArgs args)
{
    try
    {
        if (BundleTable.Bundles.Count == 0 || BundleTable.Bundles.GetBundleFor(Regex.Replace(args.Url.FilePath, "^[~/]*(.*)", "~/$1", RegexOptions.IgnoreCase)) == null)
            return;
        args.AbortPipeline();
    }
    catch (Exception ex)
    {
        this.log.Error("[Bundle]: Error while handling bundle ignore list", ex, (object) this);
    }
}

The solution

The solution is pretty simple. I created a custom config file, that set the processor for both pipelines, which looks like this (and is almost a copy of the original FXM configuration file):

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <!-- Ensure registered bundles are ignored by http request pipeline -->
        <processor patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.IgnoreList, Sitecore.Kernel']"
                   type="Sitecore.FXM.Pipelines.HttpRequest.IgnoreBundleEntries, Sitecore.FXM">
        </processor>
      </httpRequestBegin>
      
      <httpRequestEnd>
        <!-- Ensure registered bundles are ignored by http request pipeline -->
        <processor patch:before="*[1]"
                   type="Sitecore.FXM.Pipelines.HttpRequest.IgnoreBundleEntries, Sitecore.FXM">
        </processor>
      </httpRequestEnd>
    </pipelines>
  </sitecore>
</configuration>