-
Notifications
You must be signed in to change notification settings - Fork 9.8k
/
ImageTagHelper.cs
138 lines (121 loc) · 5.53 KB
/
ImageTagHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Razor.Infrastructure;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.TagHelpers;
/// <summary>
/// <see cref="ITagHelper"/> implementation targeting <img> elements that supports file versioning.
/// </summary>
/// <remarks>
/// The tag helper won't process for cases with just the 'src' attribute.
/// </remarks>
[HtmlTargetElement(
"img",
Attributes = AppendVersionAttributeName + "," + SrcAttributeName,
TagStructure = TagStructure.WithoutEndTag)]
public class ImageTagHelper : UrlResolutionTagHelper
{
private const string AppendVersionAttributeName = "asp-append-version";
private const string SrcAttributeName = "src";
/// <summary>
/// Creates a new <see cref="ImageTagHelper"/>.
/// </summary>
/// <param name="fileVersionProvider">The <see cref="IFileVersionProvider"/>.</param>
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/> to use.</param>
/// <param name="urlHelperFactory">The <see cref="IUrlHelperFactory"/>.</param>
// Decorated with ActivatorUtilitiesConstructor since we want to influence tag helper activation
// to use this constructor in the default case.
[ActivatorUtilitiesConstructor]
public ImageTagHelper(
IFileVersionProvider fileVersionProvider,
HtmlEncoder htmlEncoder,
IUrlHelperFactory urlHelperFactory)
: base(urlHelperFactory, htmlEncoder)
{
FileVersionProvider = fileVersionProvider;
}
/// <summary>
/// Creates a new <see cref="ImageTagHelper"/>.
/// This constructor is obsolete and will be removed in a future version.
/// </summary>
/// <param name="hostingEnvironment">The <see cref="IHostingEnvironment"/>.</param>
/// <param name="cacheProvider">The <see cref="TagHelperMemoryCacheProvider"/>.</param>
/// <param name="fileVersionProvider">The <see cref="IFileVersionProvider"/>.</param>
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/> to use.</param>
/// <param name="urlHelperFactory">The <see cref="IUrlHelperFactory"/>.</param>
[Obsolete("This constructor is obsolete and will be removed in a future version.")]
public ImageTagHelper(
IWebHostEnvironment hostingEnvironment,
TagHelperMemoryCacheProvider cacheProvider,
IFileVersionProvider fileVersionProvider,
HtmlEncoder htmlEncoder,
IUrlHelperFactory urlHelperFactory)
: base(urlHelperFactory, htmlEncoder)
{
HostingEnvironment = hostingEnvironment;
Cache = cacheProvider.Cache;
FileVersionProvider = fileVersionProvider;
}
/// <inheritdoc />
public override int Order => -1000;
/// <summary>
/// Source of the image.
/// </summary>
/// <remarks>
/// Passed through to the generated HTML in all cases.
/// </remarks>
[HtmlAttributeName(SrcAttributeName)]
public string Src { get; set; }
/// <summary>
/// Value indicating if file version should be appended to the src urls.
/// </summary>
/// <remarks>
/// If <c>true</c> then a query string "v" with the encoded content of the file is added.
/// </remarks>
[HtmlAttributeName(AppendVersionAttributeName)]
public bool AppendVersion { get; set; }
/// <summary>
/// Gets the <see cref="IWebHostEnvironment"/> for the application.
/// This property is obsolete and will be removed in a future version.
/// </summary>
[Obsolete("This property is obsolete and will be removed in a future version.")] // Remove after .NET 6.
protected internal IWebHostEnvironment HostingEnvironment { get; }
/// <summary>
/// Gets the <see cref="IMemoryCache"/> used to store globbed urls.
/// This property is obsolete and will be removed in a future version.
/// </summary>
[Obsolete("This property is obsolete and will be removed in a future version.")] // Remove after .NET 6.
protected internal IMemoryCache Cache { get; }
internal IFileVersionProvider FileVersionProvider { get; private set; }
/// <inheritdoc />
public override void Process(TagHelperContext context, TagHelperOutput output)
{
ArgumentNullException.ThrowIfNull(context);
ArgumentNullException.ThrowIfNull(output);
output.CopyHtmlAttribute(SrcAttributeName, context);
ProcessUrlAttribute(SrcAttributeName, output);
if (AppendVersion)
{
EnsureFileVersionProvider();
// Retrieve the TagHelperOutput variation of the "src" attribute in case other TagHelpers in the
// pipeline have touched the value. If the value is already encoded this ImageTagHelper may
// not function properly.
Src = output.Attributes[SrcAttributeName].Value as string;
output.Attributes.SetAttribute(SrcAttributeName, FileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, Src));
}
}
private void EnsureFileVersionProvider()
{
if (FileVersionProvider == null)
{
FileVersionProvider = ViewContext.HttpContext.RequestServices.GetRequiredService<IFileVersionProvider>();
}
}
}