ASP.NET MVC 4 Bundling and Minification: wrong paths in Debug Mode with Url Rewrite - asp.net-mvc

I want to use the ASP.NET MVC 4 Bundling and Minification feature, please assume that we run the debug mode so nothing is bundled, but each reference is simply rendered to single tags. Locally everything works fine:
Example
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
}
When calling #Scripts.Render("~/bundles/jquery") from the view now, a tag similar to this is generated:
<script src="/Scripts/jquery-1.8.2.js"></script>
The result is the same if I would just write:
<script src="#Url.Content("~/Scripts/jquery-1.8.2.js")"></script>
But when I deploy everything to a test server in the internet (still using the debug mode), there is some Url rewriting enabled, where I route specific domains or subdomains to specific folders.
For example, if the domain is sub1.example.com then forward to example.com/__sub1__ and in case of sub2.example.com forward to example.com/__sub2__ and so on. When I open sub1.example.com in the browser, there is usually no clue that this forward happens, the Url doesn't change, all Urls remain working and so do references generated using the Url.Content(...) method.
But for some strange reason, the call to #Scripts.Render("~/bundles/jquery") now renders something like this:
<script src="/__sub1__/Scripts/jquery-1.8.2.js"></script>
Please note the "/sub1" part which is the part which shouldn't be generated and never appear somewhere in the rendered html code and leads to a 404 because the url rewrite forward fails.
While...
<script src="#Url.Content("~/Scripts/jquery-1.8.2.js")"></script>
...still renders the correct relative Path to "/Scripts/jquery-1.8.2.js". And i never had other problems with rewriting the Urls like this. And I don't want to get rid of this rewriting.
Obviously, the same applies to style sheets.
Any ideas what I could try?

This is a bug with the current implementation of the script/style helpers, this should be fixed with the 1.1-alpha1 release that should be available shortly(early Oct) as the support for using the VirtualPathProvider registered with ASP.NET has fixed this general class of issue (resolving resource paths correctly).

Related

ASP.net MVC bundles https

asp.net mvc bundles do not render for https.
here is my code:
bundles.Add(new StyleBundle("~/Content/css/css").Include("~/Content/css/custom.css"));
View
#Styles.Render("~/Content/css/css")
And the error code I get is:
Mixed Content: The page at 'https://domain/' was loaded over HTTPS, but requested an insecure stylesheet 'http://domain:443/Content/css/custom.css'. This request has been blocked; the content must be served over HTTPS.
Do you have ~/Content/css/css as a real path in your app?
IIS is probably trying to handle the request.
Rename your bundle or the folder in your app and it should work.
So try this:
bundles.Add(new StyleBundle("~/Content/core.css").Include("~/Content/css/custom.css"));
Then in your view:
#Styles.Render("~/Content/core.css")
The style bundle name can be anything you want, it doesn't have to be related to the real location of your CSS file.
Update
If you are getting mixed content errors, that's because some of your content is coming over HTTPS and other content is coming over HTTP.
The best way to overcome this problem is use // on all your content.
So say for example you have an image like this
<img src="http://website.com/images/smiley.gif">
change it too
<img src="//website.com/images/smiley.gif">
That should stop your mixed content warnings.
Use a different bundle folder
Like, Update
bundles.Add(new StyleBundle("~/Content/css/css").Include("~/Content/css/custom.css"));
To
bundles.Add(new StyleBundle("~/CssBundles/css/css").Include("~/Content/css/custom.css"));
This issue happens if you use an existing project folder for the bundle location.

Nested application ignores bundles

I'm trying to run my ASP.NET MVC 5.2.3.0 application as nested application so that I can access it as a subfolder, like http://example.com/my-application.
I've added it to an existing application by choosing Add Application a chosen separate application pool.
When I run my-application on its own URL it works fine however when I try to run it as http://example.com/my-application it refuses to render bundles, neither style nor js.
What I have tried so far:
I have tried to enable and disable bundling and minification. When it's disabled Styles.Render adds nothing to markup. When it's enabled invalid link to bundle is added to markup, for example <link href="/calc/bundles/styles/mainlayout?v=" rel="stylesheet"/> and the link returns empty document.
I have tried to put my-application to empty website to ensure no side effects inherited. No difference here.
I have tried to put brand new application side by side with my-application and bundling worked fine there so it must be something wrong with my application and I can not find what exactly.
I have tried to ILSpy System.Web.Optimization code but couldn't find any help there.
I have failed to debug System.Web.Optimization as my VS just hung.
I didn't find any conflicting routes with my-application address.
If anyone faced the same issue then any advice appreciated.
Thanks.
UPDATE: I found what causes the issue. We intensively use T4MVC and we use it for bundles configuration as well. So our bundle declaration looks something like:
bundles.Add(new ScriptBundle("~/bundles/scripts")
.Include("~" + Links.Scripts.Script1_js, "~" + Links.Scripts.Script2_js));
And "~" + Links.Scripts.Script1_js for nested application gives me ~/my-application/scripts/script1.js while VirtualPathProvider from inside Include method expects it to be ~/scripts/script1.js.
So the question transforms into: does anyone know how to prevent T4MVC from adding nested application path onto static files links so that application isn't aware of being nested? I bet #David Ebbo knows how to achieve this :)

How replace '~' symbol in MVC with physical path

In Mvc application if the Layout is added with
#Styles.Render("~/Content/themes/base/css")
#Scripts.Render("~/bundles/jquery") .
Need a solution to replace the
~
symbol .So that Output should not be like
/Content/themes/base/jquery.ui.core.css in render page .
Instead
localhost:xxxxx/Content/themes/base/jquery.ui.core.css .
This Localhost need to be added when mvc application is run under IISExpress wherein It get modified to hosted application path when hosted into the server
As far as I know, the path used in the .Render() calls is just an identifier or key that will produce the paths for the files that were added to it earlier.
This is what you'd normally find in BundleConfig.cs:
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
The ~/bundles/ part is never sent to the output when .Render() is called. What is sent are the actual (translated) paths from the .Include() call.
You should always make those paths start with "~/" so they will be output correctly. I have never found the need to include the server name, because the browser will by default request the file from the same server that delivered the web page.

MVC ScriptBundle CDN version regular and min versions of AngularJS

From what I have read, I know that MVC bundles can "smartly" include the correct js file (minified or regular) based on whether you are debugging or not. Ideally, I'd like it to load the standard AngularJS when I'm debugging, and the minified version when I am not.
I have the following in my BundleConfig.cs:
bundles.UseCdn = true;
bundles.Add(new ScriptBundle("~/bundles/angular", "https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.js")
.Include(~/Scripts/angular.js"));
and in my view:
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/angular")
}
It doesn't seem to work unless I add BundleTable.EnableOptimizations = true; to BundleConfig.cs, but I am skeptical of this. Is this OK to leave in for development AND production? Is this forcing it to always use the regular or minified version in all cases, as opposed to smartly switching like I want? From what I can tell, it appears to be using the non-minified version regardless of whether I am running with the debugger or not, or in release configuration or not.
The other option seemed to be setting debug=false in the web.config, but this prevents me from debugging without manually modifying the file, and I'd like it to be handled automatically if possible.
Then I noticed that MVC uses a * syntax for jquery, which happens to have normal and minified versions included:
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
So I tried .Include(~/Scripts/angular*")); thinking it was a wildcard that would include .js or .min.js as appropriate but that didn't seem to work either.
Should I be doing something differently?

My _javascript file cannot be found

I have some javascript files that are named starting with an underscore. When I publish these it seems they can't be found. Is there some rule that stops these being viewed by the browser when running on IIS? I think I remember something like that for the cshtml files but didn't know that applies to js files.
I found the following post, which talks about files with "_" prefix: Why does Razor _layout.cshtml have a leading underscore in file name?.
By convention, the Razor pages that cannot be shown by the browser via direct request are prefixed with "_". Following is one of the comments from the post:
Razor was developed for ASP.NET Web Pages (WebMatrix), which doesn't
have the same sort of protection built in regarding Views folders and
Routing that you get within MVC. Since layout pages in Web Pages are
not intended to be served directly, they are prefixed with the
underscore. And the Web Pages framework has been configured not to
allow files with leading underscores in their names from being
requested directly.
In your View is the reference to them pointed to the correct path?
<script src="#Url.Content("~/Scripts/jquery-custom.js")" type="text/javascript"></script>
I would also hit Control + F5 several times after the page loads to make sure it is not cached and that is the reason it is not pulling down.

Resources