Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New ASP.NET Bundling Features - How can i programmatically refresh a certain bundle?

I'm mucking around with the new ASP.NET bundling features (using the System.Web.Optmization 1.0.0-beta pre-release) in my ASP.NET MVC 3 web application.

Works great.

However, we have certain dynamic CSS/JS which is stored in the database.

I want to get this added to a seperate bundle for my core bundle, say "DynamicBundle". I know how to do that, not a problem.

Now my question is, when this CSS/JS is changed in the database, that bundle needs to be "refreshed" so that the content of those files are re-read in to the bundle.

Essentially, i need ASP.NET to re-generate that magic guid/string that is appended to the bundle URL.

Ideally, i'd only like to refresh a specific bundle, not the entire bundle table.

Is there a way to do this?

EDIT:

Okay second problem, can't figure out how to add the dynamic CSS/JS to the bundle. bundle.AddFile takes a virtual path to a file, but it's not a physical file, it's a string. How am i going to do this? Surely i don't have to write out string to files first?

EDIT 2: So i've decided not to bundle my dynamic content. For 2 reasons:

  1. It's only 1 file, so i'm not gaining any "bundling" benefits
  2. Bundling is designed for static content, this is not

So what i've done is manually minified my dynamic css/js at runtime (once, then cached). That way i can easily refresh it, by simply clearing the cache.

That being said, this is still a relevant question (refreshing bundles) so i'll leave it open..

like image 503
RPM1984 Avatar asked Mar 28 '12 23:03

RPM1984


2 Answers

That "that magic guid/string" is a hash of the combined file contents.

You can test this with the following workflow which assumes that you have a mybundle.css. If you use Fiddler to watch the traffic, you will see it request something with a hash like

http://localhost:20206/mybundle.css?v=-6520265193368900210

Now, "touch" one of the files in the bundle as much as you want without actually changing the contents. The file is newer (LastModified / LastWrite is more recent), but the hash remains constant as it is being computed from the same combined contents. You could even add spaces to the file since those would be minified out.

http://localhost:20206/mybundle.css?v=-6520265193368900210

Next, actually make a change. Perhaps set a border to 2px instead of 1px. The hash will change now, since the contents feeding the hash have changed.

http://localhost:20206/mybundle.css?v=-4725541136976015445

Finally, set the border back to what it was (in the above example, back to 1px). The "magic string" is actually not random or magic at all. Instead, it returns to the matching one-way hash computed from the contents.

http://localhost:20206/mybundle.css?v=-6520265193368900210

Now you can rest easy that the hash will update only when it is needed, without manual intervention.

As for the other part of your question,

when this CSS/JS is changed in the database, that bundle needs to be "refreshed" so that the content of those files are re-read in to the bundle.

I think we just reverse the thinking. Instead of refreshing the bundle to trigger a re-read, we update the files to trigger the refresh. When ASP.NET sees the file(s) change, it will recombine the contents and update the hash.

like image 89
David Ruttka Avatar answered Nov 12 '22 05:11

David Ruttka


I have good news for you. Many people have been asking for virtual path provider support for scenarios similar to yours, where they have content that's not necessarily from disk, so we currently are planning on supporting VPP in the next release.

To take advantage of this support, you will have to implement a VPP for your dynamic js/css.

VPP also has cache dependency mechanisms built in, so we should be able to use those to automatically flush the correct bundle cache entry for you.

like image 42
Hao Kung Avatar answered Nov 12 '22 06:11

Hao Kung