ASP.NET Optimization Framework (JS and CSS reduction and bundle) using CDN and Hashcontent (Cache Buster or Fingerprint)

! warn! ! !

The accepted answer is good, but if you have a high-traffic website, it is possible to append v= multiple times. The code includes a checker.

I Have been looking for any examples or references using ASP.NET optimization framework and UseCDN = true and HashContent Number attached to the URI of Bundles. Unfortunately no luck. Below is a simplified example of my code.

My Bundle The code is very simple

bundles.UseCdn = true;

BundleTable.EnableOptimizations = true;


var stylesCdnPath = "http://myCDN.com/style.css";
bundles.Add(new StyleBundle("~/bundles/styles/style.css", stylesCdnPath).Include(
"~ /css/style.css"));

I call Render from the Master page

<%: System.Web.Optimization.Styles.Render( "~/bundles/styles/style.css")%>

The generated code is

If I disable UseCDN

/bundles/styles/style.css?v=geCEcmf_QJDXOCkNczldjY2sxsEkzeVfPt_cGlSh4dg1 

When useCDN is set to true, how to make bunlding add v=hash content?

Edit:

I tried it

<%: System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(" ~/bundles/styles/style.css",true)%>

If CdnUse = true, it will still not generate v = hash

You can’t. Setting UseCdn to true means that ASP.NET will provide bundles according to the CDN path and will not perform bundling and minification.

The query string v has a value token that is a unique identifier used
for caching. As long as the bundle doesn’t change, the ASP.NET
application will request the bundle using this token. If any file in
the bundle changes, the ASP.NET optimization framework will generate a
new token, guaranteeing that browser requests for the bundle will get
the latest bundle .

Look at the BundleCollection.ResolveBundleUrl implementation:

// System.Web.Optimization.BundleCollection
/// < summary>Returns the bundle URL for the specified virtual path, including a content hash if requested.
/// The bun dle URL or null if the bundle cannot be found.
/// The virtual path of the bundle.
/// true to include a hash code for the content; otherwise, false. The default is true.
public string ResolveBundleUrl(string bundleVirtualPath, bool includeContentHash)
{
Exception ex = ExceptionUtil.ValidateVirtualPath(bundleVirtualPath, "bundleVirtualPath");
if (ex != null)
{
throw ex;
}
Bundle bundleFor = this.GetBundleFor(bundleVirtualPath);
if (bundleFor == null)
{
return null;
}
if (this.UseCdn && !string.IsNullOrEmpty (bundleFor.CdnPath))
{
return bundleFor.CdnPath;
}
return bundleFor.GetBundleUrl(new BundleContext(this.Context, this, bundleVirtualPath), includeContentHash);< br />}

Reference: http://www.asp.net/mvc/tutorials/mvc-4/bundling-an d-minification

Update

You can manually add V hash to the CDN by implementing your own bundle and generating a hash on the ApplyTransforms call:

< /p>

public class myStyleBundle: StyleBundle
{
public myStyleBundle(string virtualPath)
:base(virtualPath)
{
}
< br /> public myStyleBundle(string virtualPath, string cdnPath)
: base(virtualPath,cdnPath)
{
MyCdnPath = cdnPath;
}

public string MyCdnPath
{
get;
set;
}

public override BundleResponse ApplyTransforms(BundleContext context, string bundleContent, System.Collections.Generic.IEnumerable bundleFiles)
{
var response = base.ApplyTransforms(context, bundleContent, bundleFiles);

base.CdnPath = string.Format("{0}?v ={1}", this.MyCdnPath, this.HashContent(response));

return response;
}

private string HashContent(BundleResponse response)< br /> {
string result ;
using (SHA256 sHA = new SHA256Managed())
{
byte[] input2 = sHA.ComputeHash(Encoding.Unicode.GetBytes(response.Content));
result = HttpServerUtility.UrlTokenEncode(input2);
}
return result;
}

}

Then, just:

bundles.Add(new myStyleBundle("~/bundles/styles/style.css", stylesCdnPath).Include(
"~/css/style.css"));

Please note that System.Web.Optimization.BundleResponse will create a hash algorithm based on environment settings:

// System.Web.Optimization.BundleResponse< br />private static SHA256 CreateHashAlgorithm()
{
if (BundleResponse.AllowOnlyFipsAlgorithms)
{
return new SHA256CryptoServiceProvider();
}
return new SHA256Managed();
}

! warn! ! !

The accepted answer is good, but if you have a high-traffic website, it is possible to append v= multiple times. The code includes a checker.

I Have been looking for any examples or references using ASP.NET optimization framework and UseCDN = true and HashContent Number attached to the URI of Bundles. Unfortunately no luck. Below is a simplified example of my code.

My Bundle The code is very simple

bundles.UseCdn = true;

BundleTable.EnableOptimizations = true;


var stylesCdnPath = "http://myCDN.com/style.css";
bundles.Add(new StyleBundle("~/bundles/styles/style.css", stylesCdnPath).Include(
"~ /css/style.css"));

I call Render from the Master page

<%: System.Web.Optimization.Styles.Render( "~/bundles/styles/style.css")%>

The generated code is

If I disable UseCDN

/bundles/styles/style.css?v=geCEcmf_QJDXOCkNczldjY2sxsEkzeVfPt_cGlSh4dg1 

When useCDN is set to true, how to make bunlding add v=hash content?

Edit:

I tried to use

<%: System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(" ~/bundles/styles/style.css",true)%>

If CdnUse = true, it will still not generate v = hash

You can’t. Setting UseCdn to true means that ASP.NET will provide bundles according to the CDN path, and will not perform bundling and minification.

The query string v has a value token that is a unique identifier used
for caching. As long as the bundle doesn’t change, the ASP.NET
application will request the bundle using this token. If any file in
the bundle changes, the ASP.NET optimization framework will generate a
new token, guaranteeing that browser requests for the bundle will get
the latest bundle.

Take a look at the BundleCollection.ResolveBundleUrl implementation:

// System.Web.Optimization.BundleCollection
/// Returns the bundle URL for the specified virtual path, including a content hash if requested.
/// The bundle URL or null if the bundle cannot be found.
/ // The virtual path of the bundle.
/// true to include a hash code for the content; otherwise, false. The default is true.
public string ResolveBundleUrl(string bundleVirtualPath, bool includeContentHash)
{
Exception ex = ExceptionUtil.ValidateVirtualPath(bundleVirtualPath, "bundleVirtualPath");
if (ex != null)
{
throw ex;
}
Bundle bundleFor = this.GetBundleFor(bundleVirtualPath);
if (bundleFor == null)< br /> {
return null;
}
if (this.UseCdn && !string.IsNullOrEmpty(bundleFor.CdnPath))
{
return bundleFor.CdnPath;
}
return bundleFor.GetBundleUrl(new BundleContext(this.Context, this, bundleVirtualPath), includeContentHash);
}

Reference: http://www.asp .net/mvc/tutorials/mvc-4/bundling-and-minification

Update

You can implement your own bundle and applyTransform Generate a hash on the s call, and manually add V hash to the CDN:

public class myStyleBundle: StyleBundle
{
public myStyleBundle(string virtualPath)< br /> :base(virtualPath)
{
}

public myStyleBundle(string virtualPath, string cdnPath)
: base(virtualPath,cdnPath)
{
MyCdnPath = cdnPath;
}

public string MyCdnPath
{
get;
set;
}

public override BundleResponse ApplyTransforms(BundleContext context, string bundleContent, System.Collections.Generic.IEnumerable bundleFiles)
{
var response = base.ApplyTransforms(context, bundleContent, bundleFiles) ;

base.CdnPath = string.Format("{0}?v={1}", this.MyCdnPath, this.HashContent(response));

return response;
}

private string HashContent(BundleResponse response)
{
string result;
using (SHA256 sHA = new SHA256Managed())
{
byte[] input2 = sHA.ComputeHash(Encoding.Unicode.GetBytes(response.Content));
result = HttpServerUtility.UrlTokenEncode(input2);
}
return result;
}

}

Then, just:

bundles.Add(new myStyleBundle("~/bundles/styles/ style.css", stylesCdnPath).Include(
"~/css/style.css"));

Please note that System.Web.Optimization.BundleResponse will create a hash according to the environment settings Algorithm:

// System.Web.Optimization.BundleResponse
private static SHA256 CreateHashAlgorithm()
{
if (BundleResponse.AllowOnlyFipsAlgorithms)
{
return new SHA256CryptoServiceProvider();
}
return new SHA256Managed();
}

Leave a Comment

Your email address will not be published.