I maintain a large legacy ASP.NET MVC application, which was recently converted to .Net Core.
I need to introduce cache busting for our JavaScript and CSS files. I appreciate this can easily be done using the asp-append-version="true" attribute on the new .Net Core script tag helper.
However, my application has script tags in over a 100 places. Adding the attribute in all those places will touch large numbers of pages, which means a lot of regression testing.
Is there a way to create a new script tag helper that inherits from the .Net Core script tag helper, and that always has the asp-append-version="true" attribute? That will give me cache busting without having to update lots of files.
...create a new script tag helper that inherits from the .Net Core script tag helper, and that always has the asp-append-version="true" attribute?
Code (View on GitHub)
using System.Linq;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Caching.Memory;
namespace AspNetCoreScriptTagHelperOverride
{
[HtmlTargetElement("script")] // A
public class MyScriptTagHelper : ScriptTagHelper
{
public MyScriptTagHelper(
IHostingEnvironment env,
IMemoryCache cache,
HtmlEncoder html,
JavaScriptEncoder js,
IUrlHelperFactory url) : base(env, cache, html, js, url) { } // B
public override void Process(TagHelperContext context, TagHelperOutput output)
{
const string appendVersion = "asp-append-version";
if (!context.AllAttributes.Any(a => a.Name == appendVersion))
{
var attributes = new TagHelperAttributeList(context.AllAttributes);
attributes.Add(appendVersion, true);
context = new TagHelperContext(attributes, context.Items, context.UniqueId);
} // E
base.AppendVersion = true; // C
base.Process(context, output); // D
}
}
}
Explanation
- A: Set the
TagName
to"script"
. - B: Implement the base constructor.
- C: Hard code
AppendVersion
to true. - D: Call the base class's
Process
. - E: Overcome
AttributeMatcher.TryDetermineMode
Usage
In _ViewImports.cshtml
remove the existing tag helper and add your override.
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AspNetCoreScriptTagHelperOverride
Be sure to use the name of your assembly.
Once that is done, your code will execute wherever there is a script
tag helper. For instance, both of the following will have AppendVersion
set to true
.
<script src="~/js/site.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/js/site.js" asp-append-version="false"></script>
This will be the the resultant HTML:
<script src="/js/site.js?v=4q1jwFhaPaZgr8WAUSrux6hAuh0XDg9kPS3xIVq36I0"></script>
See Also
https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs
来源:https://stackoverflow.com/questions/50958531/how-to-create-a-script-tag-helper-that-inherits-from-the-standard-net-core-scri