C# Web.Optimization Bundles and HTML5 cache Manifest - asp.net

I am using ASP.NET optimization package to minify and bundle the scripts, and CSS files.
I am also developing a mobile UI for my ASP.NET application which uses a HTML5 cache manifest.
The optimization package updates the version of the dynamic bundle URL when the files change and the application cache is recycled.
I would like to be able to update my manifest version whenever this happens and include the dynamic URLs the optimization package provides in the manifest.
How can I read the current version (the "v" parameter) or anything else to trigger a manifest update?
/_assets/bundles/global?v=fmbQlO0mGjXyliVEBImQIr5yoMX0Tw0tlMK45jlwHZ81
Example Code:
string version= "2.6";
StringBuilder output = new StringBuilder();
output.AppendLine("CACHE MANIFEST");
output.AppendLine(string.Format("# v{0}", ??????));
output.AppendLine("CACHE:");
output.AppendLine(Scripts.Url("~/bundles/global").ToString());
...

The Application Manifest will automatically trigger an update if it is changed.
With static assets, people usually changed a version number in a comment so that the file was changed and would trigger an update, even though the content under the CACHE, NETWORK and FALLBACK sections were unchanged.
When you are using the URLs generated by System.Web.Optimization, the URL will change when the content of any of the CSS or JavaScript files in the bundles changes. This means that the manifest file will automatically be different to the previous version of the file and will trigger an update.
There is no need to force the file to be different by updating a version comment.

Related

Laravel app serving resources that do not exist?

I am in the process of adding a Content Security Policy for a laravel application. While downloading external css and font styles to the local assets I have run into some odd template behavior.
I wanted to test that the paths to the newly downloaded libraries were correct, but when I change the name of files I downloaded and refresh, even with the browser cache disabled, it is still referencing the old location successfully. If you try to access the file in the old location directly by file path it fails (because it no longer exists).
Even more strangely, if I pull the code down to another computer and run it (I have not added the new libraries to git yet), the page still seems to think it correctly loaded that resource.
I tried clearing the following directories:
storage/framework/cache
storage/framework/sessions
storage/framework/views
and running the code again - on multiple computers, and it still reports that it is loading these files that are no longer there?
Does Laravel or commonly used front end frameworks with it store compiled templates somewhere else? I am completely perplexed...

Forcing Cache refresh after deploying new code

We are running into issue where our clients are served stale js, css files after code is deployed. We are using IIS as our webserver and our code is in ASP.Net 4.5. I did some research and figured out that ETag in conjunction with Cache-control should work. As I understand ETag is automatically generated by web server based on datetime stamp of file so I ran following steps to see why the system is not sending the latest version of js and css files.
Navigated to my website to a webpage let's call is demo.aspx.(Now assuming that demo.aspx contains reference to a.js, b.js and c.css)
Verified that a.js, b.js and c.css file were requested by browser and webserver delivered those files after I hard refersh a page(Ctrl + F5) on my website.
Clicked on some other webpage
Went to webserve and manually updated files (a.js, b.js and c.css to update datetime stamp of those files)
Navigated to demo.aspx again.
This time I see only request made to demo.aspx but not to any of the resource file (a.js, b.js and c.css).
I am at loss as to why .js files are not requested when I access my demo.aspx page.
Also, Is there any easy way to force client browsers to download latest version of .js and .css files every time I deploy code. Based on my research, I did find out that one way to do would be to rename .js and .css file. Please note that this soution won't work for us.
We do use update panel in our projects. Not sure if that has anything to do with browser not requesting js files second time
A widely used trick is to add a query string parameter that is incremented with every new version of the css or js file.
Like myScript.js?version=12. When the the number changes the browser sees it as a new file and it's downloaded rather than retrieved from cache.
Just changing the timestamp by editing the file won't work, the browser does not get the timestamp from the server. You can try this by saving an image or file from the website, they all have the timestamp of when they were being downloaded.

ASP.NET MVC - Make Cached Styles Expired upon Release using Bundling

This is how I include JavaScript files in my ASP.NET MVC application,
Bundles.Add(new ScriptBundle(ConfigBundles.Scripts).Include
(
"~/Content/Scripts/Libraries/framework-{version}.js",
"~/Content/Scripts/Libraries/controls-{version}.js"
));
My understanding is that whenever I do a new release where the referenced JavaScript files have changed, i just need to increment the version number so that user's web browsers know that they need to clear the existing cache and request the new file.
However, this same process does not seem to work for stylesheets - this is how I load them:
Bundles.Add(new StyleBundle(ConfigBundles.Styles)
.Include("~/Content/Styles/Site-{version}.css", new CssRewriteUrlTransform()));
However, this does not seem to work - when I change the name of the Site.css to include a version, the bundling doesn't seem to detect it. Furthermore, in most guides on bundling they just talk about using this feature with Scripts - I haven't seen anyone confirm that it can used with styles as well...
Am I going about this the right way?

mvc bundle and css management strategy

I developed a website, which can be used by different customers. As a result, we want to give different CSS styles and images to individual customers.
What we want is to manage CSS and images separately, so we won't need to deploy the site again just because we added some new CSS or images. As the site is under MVC, when accessing URLs such as:
www.mysite.com/customerA/myPage
www.mysite.com/customerB/myPage
we can find the customer id and find the right CSS and image to return.
The problem is that we want to bundle CSS, when the CSS or images are bundled, two issues will occur:
How the bundle detect underlying CSS file change? Is it possible?
Some users may already visited the URL and cached the bundled CSS, how can we disable the cached CSS, so it will get the new version?
The .NET bundling strategy is very intelligent in solving both of your issues. Once you create a bundle - example below:
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
And render this bundle out on your website, the output looks something like this:
<link href="/Content/css?v=xUfHQEnjwMk9UEexrvHPdvPxJduGrgz0bbI5qy5BGHY1" rel="stylesheet"/>
Notice the ?v=bigTextstring. Anytime a file in your bundle changes, the bundling framework will change the bigTextString after the ?v=. So, for your first question, yes, it will automatically detect file changes. You can get more information about how all of that process works if you visit this SO question. For your second question, the ?v= parameter, when changed, signals the client's browser that this is a different file than you had, you need to download it again.
Tommy has a great answer. I just wanted to elaborate on a few points.
First, as long as the bundle itself hasn't changed (added/removed scripts/styles or changed the location of those files), then you can freely update the files themselves without republishing the whole site. The bundler runs at runtime and looks at the last modified timestamp of the included files. If any of the files has changed, a new bundle will be generated with an updated cache-busting querystring param.
However, since the actual bundle configuration is code-based, if you add/remove items from the bundle or change the location of the file(s), such that you have to update the bundle configuration in BundleConfig.cs then you must republish, or at least also update the project DLL. This is because the code compiled within that DLL has changed.

How to pre-complie css style sheets in rails 2.3?

I have developed a new requirement for my client, I had added some css rule to an existing style-sheet file and these changes were reflecting on my local machine during development. But when I moved the changes to an staging server and restarted nginx all my functionalites are working but my css rules are not getting applied, when I checked the firebug console that particular file is getting included but my new css rules are not in there, should I pre-compile my css style-sheets if so how to do it in rails 2.3.x ...?
Thanks in advance.
Rails 2.3 does not have asset pipeline. So there is no need to precompile assets. Your assets should already be located in the Rails.root/public/stylesheets folder
Anything in Rails.root/public/ folder is served by the web server directly and it does not involve rails.
Your problem is most likely some sort of caching. You can try fetching the stylesheet directly using its URL like this
http://server.domain/stylesheets/mystyles.css
and see if your changes are reflected.
You can also check your Firebug -> Net tab to see if the style sheet is being downloaded from the server (http return code: 200 OK) or it is being picked up from the cache (http return code: 304 Not Modified)
There are ways to handle this type of issues, which rails 3.1 asset pipeline incorporates.
Using a different file name when content changes
Using the ETag header
Appending a unique hash (calculated using timestamp of the file) as a query string. For example http://domain/style.css?djfhsfhkkjdsfh where djfhsfhkkjdsfh will change every time style.css is modified.
are couple of commonly used tricks.
If you are keen on using asset pipeline with rails 2.3 you have options such as Jammit

Resources