I was wondering if anybody can help me with bundling and minifying using the new optimization namespace shipped with MVC 4. I have a Multitenant-application in which I want to decide which js files should be loaded based on settings per user. One approach would be to create all bundles upfront and change the virtual path of resolvebundleurl based on the setting of the user, but that feels not really the right way. Also I have dynamic css in a cshtml view based on user-settings, which I would like to have minified in runtime.
Any suggestions? I also see a lot of reactions in other questions to check out Requestreduce, but they are all from the same user.
What would be the best approach to handle both situations?
Thanks in advance!
Update: Not sure if it matters but I am using MVC 5.2.3 and Visual Studio 2015, question is a little old.
However I made dynamic bundling that works in _viewStart.cshtml. What I did was I made a helper class that stores bundles in a dictionary of bundles. Then at app start I pull them from the dictionary and register them. And I made a static boolen "bundlesInitialzed" so that the bundles only add to the dictionary once.
Example Helper:
Example _ViewStart.cshtml
Note: This should be updated to use thread locking to prevent 2 requests entering the bundle code before the first one exits.
The way this works is the view start runs on the first request to the site after an app pool reset. It calls the RegisterBundle on the helper and passes the ScriptBundle or StyleBundle to the dictionary in the order RegisterBundles is called.
When FinalizeBundles is called you can specify True which will force optimizations regardless of web.config debug setting, or leave it null or use the constructor without that parameter to have it respect the web.config setting. Passing false will force it to use no optimization even if debug is true. FinalizeBundles Registers the bundles in the bundles table and set's _BundlesFinalized to true.
Once finalized, an attempt to call RegisterBundle again will throw an exception, it's frozen at that point.
This setup allows you to add new bundles to view start and reset the app pool to get them to take effect. The original goal I had writing this was because I am making something others will use so I wanted them to be able to completely change the front end UI without having to rebuild the source to change the bundles.
i wrote a helper function to dynamic minify my css & js
usage
~/views/Home/Test1.cshtml
~/Views/Home/Test1.cshtml.css
~/Views/Home/Test1.cshtml.js
in Test1.cshtml
but ofcoz, i put most of my sripts,styles in ~/Scripts/.js, ~/Content/.css
and register them in Appp_Start
We considered supporting dynamic bundles early on, but the fundamental issue with that approach is multi server scenarios (i.e. cloud) won't work. If all bundles are not defined in advance, any bundle requests that get sent to a different server than the one that served the page request will get 404 response(as the bundle definition would only exist on server that handled the page request). As a result, I would suggest creating all bundles up front, that's the mainline scenario. Dynamic configuration of bundles might work as well, but that is not a fully supported scenario.
One approach you can take is building the bundle dynamically when the application starts. So if your scripts are located in
~/scripts
you can do:Then your markup can look like this
@Scripts.Render("~/Scripts/Libs/js")
Note: I'm using the latest nuget package for system.web.optimization (now Microsoft.AspNet.Web.Optimization) located here. Scott Hanselman has a good post about it.