This is my story...
There were a few issues. The first and most simple was that an image I needed was in the file system (and accessible when running in debug mode) but did not exist in the project, so it wasn't deployed. This is a good explanation of how to do it: How do I add an existing directory tree to a project in Visual Studio?
My major issue was related to bundling (which I never took much notice of)
The thing is bundling does not happen in debug mode (i.e. when you run locally)
Bundling does happen when you deploy a release version.
So your app runs sweet until you deploy it.
If you want to force your debug version to perform bundling, so you can discover these issues before deployment (I will be doing this from now on), add this line inside your RegisterBundles
public static void RegisterBundles(BundleCollection bundles)
BundleTable.EnableOptimizations = true;
Conversely, if you are over trying to fix it and just want to see your shiny web app functioning, add this line instead before deployment:
BundleTable.EnableOptimizations = false;
Which will disable bundling altogether and make your deployed app work like your debug app. Keep in mind bundling is there for performance so you'll probably take a performance hit.
Anyway...........
I read a lot about bundling but I couldn't find specifics on the meaning of the parameters to ScriptBundle
, particularly the first parameter.
After a while I worked out that this:
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
means:
Take the files
- ~/Scripts/bootstrap.js
- ~/Scripts/respond.js
And bundle them up (minify and squish them into a single GET) then put them in the actual web folder ~/bundles/bootstrap
So not only is ~/bundles/bootstrap a key that you use to identify the bundle (in the call to bundle and in your view), it is also a physical path on the web server where the bundle is stored and called from
Not knowing what this thing was for, I had a call like this:
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css",
"~/Content/themes/base/all.css",
"~/Content/select2.css"
));
THE PROBLEM WAS: ~/Content/css is an actual physical folder that already exists so the bundling was somehow confused. Changing this first parameter to a different path fixed it.
So... if you have this problem do two things:
Make sure all your StyleBundle keys (the first string in the StyleBundle call) start with ~/bundles
(or something suitably unique), just to make sure that they can't possibly reference a real folder
I also made sure that none of my referenced files were the .min file. Not sure of this made a difference but I found it on another stackexchange answer so I did it anyway.
My problem now is that I need to only include the right stylesheets in the right order in bundles.
If you bundle everything or miss out a css file or even put them in the wrong order, your bundled css will not be applied the same as your debug css and your page will be a misshapen deformed monster
For example I needed to put my site.css after bootstrap.css so that my custom site styling would override generic bootstrap styling. I also neede to use .IncludeFolder to include the entire contents of the jqueryui css folder
.. and still I have an issue that jqueryui styles reference images in a subfolder. (so it still has the incorrect relative path issue)