简体   繁体   中英

Get MVC Bundle Querystring

Is it possible to detect a bundle querystring in ASP.NET MVC?

For example if I have the following bundle request:

/css/bundles/mybundle.css?v=4Z9jKRKGzlz-D5dJi5VZtpy4QJep62o6A-xNjSBmKwU1

Is it possible to extract the v querystring?:

4Z9jKRKGzlz-D5dJi5VZtpy4QJep62o6A-xNjSBmKwU1


I've tried doing this in a bundle transform, but with no luck. I found that even with UseServerCache set to false the transform code didn't always run.

It's been a while since I've worked with the ASP Bundler (I remember it being terrible), and these notes are from my memory. Please verify that it's still valid. Hopefully this will provide a starting point for your search.

To tackle this problem you'll want to explore around in System.Web.Optimization namespace .

Of most importance is the System.Web.Optimization.BundleResponse class, which has a method named GetContentHashCode() which is exactly what you want. Unfortunately, MVC Bundler has a bad architecture and I'm willing to bet that this is still an internal method. This means you won't be able to call it from your code.


Update

Thanks for the verification. So it looks like you have a few ways of accomplishing your goal:

  1. Compute the hash your self using the same algorithm as ASP Bundler

  2. Use reflection to call into the internal method of the Bundler

  3. Get the URL from bundler (there is a public method for this I believe) and extract the query string, then extract the hash from that (using any string extraction methods)

  4. Get angry at Microsoft for bad design

Lets go with #2 (Be careful, since its marked as internal and not part of the public API, a rename of the method by the Bundler team will break things)

//This is the url passed to bundle definition in BundleConfig.cs
string bundlePath = "~/bundles/jquery";
//Need the context to generate response
var bundleContext = new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundlePath);

//Bundle class has the method we need to get a BundleResponse
Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath);
var bundleResponse = bundle.GenerateBundleResponse(bundleContext);

//BundleResponse has the method we need to call, but its marked as
//internal and therefor is not available for public consumption.
//To bypass this, reflect on it and manually invoke the method
var bundleReflection = bundleResponse.GetType();

var method = bundleReflection.GetMethod("GetContentHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

//contentHash is whats appended to your url (url?###-###...)
var contentHash = method.Invoke(bundleResponse, null);

The bundlePath variable is the same name that you gave to the bundle (from BundleConfig.cs )

Hope this helps! Good Luck!

Edit: Forgot to say that it would be a good idea to add a test around this. The test would check for the existence of the GetHashCode function. This way, in the future, should the internals of the Bundler change the test will fail and you'll know where the problem is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM