I've been trying out the new minification and bundling feature in ASP.NET MVC 4, and it works great as long as you use the default folder conventions for css and js files.
/Content
/Scripts
I usually put css and script in a folder called Static like this
/Static/Css
/Static/Js
I tried to register my own bundles like this:
public static class BundleCollectionExtensions
{
public static void RegisterScriptsAndCss(this BundleCollection bundles)
{
var bootstrapCss = new Bundle("~/Static/Css", new CssMinify());
bootstrapCss.AddDirectory("~/Static/Css", "*.css");
bootstrapCss.AddFile("~/Static/Css/MvcValidation.css");
bootstrapCss.AddFile("~/Static/Css/bootstrap-responsive.min.css");
bootstrapCss.AddFile("~/Static/Css/bootstrap.min.css");
bundles.Add(bootstrapCss);
var bootstrapJs = new Bundle("~/Static/Js", new JsMinify());
bootstrapJs.AddDirectory("~/Static/Js", "*.js");
bootstrapJs.AddFile("~/Static/Js/jquery-1.7.1.min.js");
bootstrapJs.AddFile("~/Static/Js/jquery.validate.min.js");
bootstrapJs.AddFile("~/Static/Js/jquery.validate.unobtrusive.min.js");
bootstrapJs.AddFile("~/Static/Js/bootstrap.min.js");
bootstrapJs.AddFile("~/Static/Js/gunsforhire.js");
bundles.Add(bootstrapJs);
}
}
And in
Global.ascx.cs
I did this:
BundleTable.Bundles.RegisterScriptsAndCss();
The generated markup looks like this:
<link href="/Static/Css?v=D9JdmLZFFwjRwraNKfA1uei_YMoBoqLf-gFc0zHivM41" rel="stylesheet" type="text/css" />
<script src="/Static/Js?v=mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1" type="text/javascript"></script>
However It's doesn't work, the request looks like this:
Request URL:http://localhost:49603/Static/Js?v=mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Request Method:GET
Status Code:301 Moved Permanently (from cache)
Query String Parametersview URL encoded
v:mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Request URL:http://localhost:49603/Static/Js/?v=mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Request Method:GET
Status Code:404 Not Found
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:49603
Referer:http://localhost:49603/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11
Query String Parametersview URL encoded
v:mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Response Headersview source
Cache-Control:private
Content-Length:4757
Content-Type:text/html; charset=utf-8
Date:Thu, 01 Mar 2012 19:05:44 GMT
Server:Microsoft-IIS/7.5
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B? QzpcQENvZGVccGVsbGVccGVsbGVoZW5yaWtzc29uLnNlXHNyY1xXZWJcU3RhdGljXEpzXA==?=
What am I doing wrong?
Update
I think I was finally able to solve this by doing the following:
Removing the AddDirectory calls
bootstrapCss.AddDirectory("~/Static/Css", "*.css");
Giving the bundles paths that do not reflect the real directory structure
What you are doing "wrong" is that your bundle path corresponds to a REAL path. As I understand it, when the request for "/Static/Css?v=D9JdmLZFFwjRwraNKfA1uei_YMoBoqLf-gFc0zHivM41" comes in, the routing engine first looks for a physical path. It finds a match with your folder "static" and it tries to find a file in it that matches "Css?v=D9JdmLZFFwjRwraNKfA1uei_YMoBoqLf-gFc0zHivM41". When it can't find one, because it doesn't exist, it gives a 404. (I've also seen an access denied.) When the routing engine can't find a physical file path it then looks to other handlers like bundling and minification to serve up the request.
Anyway I think you've figured it out from your comments but I'm not sure it will be very clear to anyone that finds your question. Simply change your registration from:
var bootstrapCss = new Bundle("~/Static/Css", new CssMinify());
to:
var bootstrapCss = new Bundle("~/bundles/Css", new CssMinify());
If you make that change, your issue will go away, (granted there is no physical path that corresponds to "bundles".
if done this a few days ago and it worked well. i created a folder named Helper
and then i created a new class called CssJsBuilder
.
my class looks like this:
public static void Initializing()
{
IBundleTransform jstransformer;
IBundleTransform csstransformer;
#if DEBUG
jstransformer = new NoTransform("text/javascript");
csstransformer = new NoTransform("text/css");
#else
jstransformer = new JsMinify();
csstransformer = new CssMinify();
#endif
var bundle = new Bundle("~/Scripts/js", jstransformer);
bundle.AddFile("~/Scripts/jquery-1.6.2.js", true);
bundle.AddFile("~/Scripts/jquery-ui-1.8.11.js", true);
bundle.AddFile("~/Scripts/jquery.validate.unobtrusive.js", true);
bundle.AddFile("~/Scripts/jquery.unobtrusive-ajax.js", true);
bundle.AddFile("~/Scripts/jquery.validate.js", true);
bundle.AddFile("~/Scripts/modernizr-2.0.6-development-only.js", true);
bundle.AddFile("~/Scripts/AjaxLogin.js", true);
bundle.AddFile("~/Scripts/knockout-2.0.0.debug.js", true);
bundle.AddFile("~/Scripts/bootstrap.js", true);
bundle.AddFile("~/Scripts/dungeon.custom.js", true);
BundleTable.Bundles.Add(bundle);
bundle = new Bundle("~/Content/css", csstransformer);
bundle.AddFile("~/Content/bootstrap-responsive.css", true);
bundle.AddFile("~/Content/bootstrap.css", true);
BundleTable.Bundles.Add(bundle);
bundle = new Bundle("~/Content/themes/base/css", csstransformer);
bundle.AddFile("~/Content/themes/base/jquery.ui.core.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.resizable.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.selectable.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.accordion.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.autocomplete.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.button.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.dialog.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.slider.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.tabs.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.datepicker.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.progressbar.css", true);
bundle.AddFile("~/Content/themes/base/jquery.ui.theme.css", true);
BundleTable.Bundles.Add(bundle);
}
After that. Go to Global.asax
:
- Remove or comment out
BundleTable.Bundles.RegisterTemplateBundles()
- Add
CssJsBuilder.Initializing()
to theApplication_Start()
Method. - Recreate Project and then start it again.
Hope this works for you, too.
In Global.asax.cs replace
BundleTable.Bundles.RegisterTemplateBundles();
with
BundleTable.Bundles.EnableDefaultBundles();
Here is how it worked for me.
This is simplified version I only use default.aspx file no global.asax (you can us it if you want)
In this example I use 2 directories Content2 and Scripts2
in Content2 I have 2 css files one for class="naziv" and other for class="naziv2"
in Scripts2 there are 2 files one with function f1() definition and other with f2() definition
in /bin directory there should be 3 files:
Microsoft.Web.Infrastructure.dll, System.Web.Optimization.dll, WebGrease.dll
<%@ Page Title="Home Page" Language="vb" debug="true"%>
<%@ Import namespace="System.Web.Optimization" %>
<script runat="server" >
Sub Page_Load(sender As Object, e As EventArgs)
System.Web.Optimization.BundleTable.EnableOptimizations = True ''true will force optimization even if debug=true
Dim siteCssBundle = New StyleBundle("~/Content2/css")
siteCssBundle.IncludeDirectory("~/Content2", "*.css")
BundleTable.Bundles.Add(siteCssBundle)
Dim siteJsBundle = New ScriptBundle("~/Scripts2/js")
siteJsBundle.IncludeDirectory("~/Scripts2", "*.js")
BundleTable.Bundles.Add(siteJsBundle)
End Sub
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
</head>
<body onload="f1(); f2();">
<%: Styles.Render("~/Content2/css")%>
<%: Scripts.Render("~/Scripts2/js")%>
<br />
<span class="naziv">Span 1</span> <br />
<span class="naziv2">Span 2</span> <br />
</body>
</html>
来源:https://stackoverflow.com/questions/9522407/asp-net-optimization-bundling