Replaced WebUtility.HtmlEnode with IHtmlEncoder.HtmlEncode

This commit is contained in:
Ajay Bhargav Baaskaran 2015-02-17 12:09:44 -08:00
parent e4b1242328
commit 81c3b75980
54 changed files with 658 additions and 348 deletions

View File

@ -7,6 +7,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc
{
@ -22,13 +23,14 @@ namespace Microsoft.AspNet.Mvc
public AntiForgery([NotNull] IClaimUidExtractor claimUidExtractor,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] IAntiForgeryAdditionalDataProvider additionalDataProvider,
[NotNull] IOptions<MvcOptions> mvcOptions)
[NotNull] IOptions<MvcOptions> mvcOptions,
[NotNull] IHtmlEncoder htmlEncoder)
{
var config = mvcOptions.Options.AntiForgeryOptions;
var serializer = new AntiForgeryTokenSerializer(dataProtectionProvider.CreateProtector(_purpose));
var tokenStore = new AntiForgeryTokenStore(config, serializer);
var tokenProvider = new TokenProvider(config, claimUidExtractor, additionalDataProvider);
_worker = new AntiForgeryWorker(serializer, config, tokenStore, tokenProvider, tokenProvider);
_worker = new AntiForgeryWorker(serializer, config, tokenStore, tokenProvider, tokenProvider, htmlEncoder);
}
/// <summary>

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc
{
@ -19,18 +20,21 @@ namespace Microsoft.AspNet.Mvc
private readonly ITokenStore _tokenStore;
private readonly ITokenValidator _validator;
private readonly ITokenGenerator _generator;
private readonly IHtmlEncoder _htmlEncoder;
internal AntiForgeryWorker([NotNull] IAntiForgeryTokenSerializer serializer,
[NotNull] AntiForgeryOptions config,
[NotNull] ITokenStore tokenStore,
[NotNull] ITokenGenerator generator,
[NotNull] ITokenValidator validator)
[NotNull] ITokenValidator validator,
[NotNull] IHtmlEncoder htmlEncoder)
{
_serializer = serializer;
_config = config;
_tokenStore = tokenStore;
_generator = generator;
_validator = validator;
_htmlEncoder = htmlEncoder;
}
private void CheckSSLConfig(HttpContext httpContext)
@ -107,11 +111,16 @@ namespace Microsoft.AspNet.Mvc
SaveCookieTokenAndHeader(httpContext, newCookieToken);
// <input type="hidden" name="__AntiForgeryToken" value="..." />
var retVal = new TagBuilder("input");
retVal.Attributes["type"] = "hidden";
retVal.Attributes["name"] = _config.FormFieldName;
retVal.Attributes["value"] = _serializer.Serialize(formToken);
return retVal;
var inputTag = new TagBuilder("input", _htmlEncoder)
{
Attributes =
{
{ "type", "hidden" },
{ "name", _config.FormFieldName },
{ "value", _serializer.Serialize(formToken) }
}
};
return inputTag;
}
// [ ENTRY POINT ]

View File

@ -5,7 +5,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
@ -25,12 +24,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
return htmlHelper.ViewData.ModelMetadata.IsNullableValueType ?
BooleanTemplateDropDownList(htmlHelper, value) :
BooleanTemplateCheckbox(value ?? false);
BooleanTemplateCheckbox(value ?? false, htmlHelper);
}
private static string BooleanTemplateCheckbox(bool value)
private static string BooleanTemplateCheckbox(bool value, IHtmlHelper htmlHelper)
{
var inputTag = new TagBuilder("input");
var inputTag = new TagBuilder("input", htmlHelper.HtmlEncoder);
inputTag.AddCssClass("check-box");
inputTag.Attributes["disabled"] = "disabled";
inputTag.Attributes["type"] = "checkbox";
@ -44,7 +43,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
private static string BooleanTemplateDropDownList(IHtmlHelper htmlHelper, bool? value)
{
var selectTag = new TagBuilder("select");
var selectTag = new TagBuilder("select", htmlHelper.HtmlEncoder);
selectTag.AddCssClass("list-box");
selectTag.AddCssClass("tri-state");
selectTag.Attributes["disabled"] = "disabled";
@ -55,7 +54,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
foreach (var item in TriStateValues(value))
{
var encodedText = htmlHelper.Encode(item.Text);
var option = DefaultHtmlGenerator.GenerateOption(item, encodedText);
var option = DefaultHtmlGenerator.GenerateOption(item, encodedText, htmlHelper.HtmlEncoder);
builder.Append(option);
}
@ -181,7 +180,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
string.Empty :
htmlHelper.ViewData.TemplateInfo.FormattedModelValue.ToString();
return HyperlinkTemplate(uriString, linkedText);
return HyperlinkTemplate(uriString, linkedText, htmlHelper);
}
public static string HiddenInputTemplate(IHtmlHelper htmlHelper)
@ -233,7 +232,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
continue;
}
var divTag = new TagBuilder("div");
var divTag = new TagBuilder("div", htmlHelper.HtmlEncoder);
if (!propertyMetadata.HideSurroundingHtml)
{
@ -293,13 +292,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
string.Empty :
htmlHelper.ViewData.TemplateInfo.FormattedModelValue.ToString();
return HyperlinkTemplate(uriString, linkedText);
return HyperlinkTemplate(uriString, linkedText, htmlHelper);
}
// Neither uriString nor linkedText need be encoded prior to calling this method.
private static string HyperlinkTemplate(string uriString, string linkedText)
private static string HyperlinkTemplate(string uriString, string linkedText, IHtmlHelper htmlHelper)
{
var hyperlinkTag = new TagBuilder("a");
var hyperlinkTag = new TagBuilder("a", htmlHelper.HtmlEncoder);
hyperlinkTag.MergeAttribute("href", uriString);
hyperlinkTag.SetInnerText(linkedText);

View File

@ -257,7 +257,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
continue;
}
var divTag = new TagBuilder("div");
var divTag = new TagBuilder("div", htmlHelper.HtmlEncoder);
if (!propertyMetadata.HideSurroundingHtml)
{

View File

@ -7,13 +7,13 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering.Expressions;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc.Rendering
{
@ -25,6 +25,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
private readonly IScopedInstance<ActionBindingContext> _bindingContextAccessor;
private readonly IModelMetadataProvider _metadataProvider;
private readonly IUrlHelper _urlHelper;
private readonly IHtmlEncoder _htmlEncoder;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultHtmlGenerator"/> class.
@ -33,12 +34,14 @@ namespace Microsoft.AspNet.Mvc.Rendering
[NotNull] AntiForgery antiForgery,
[NotNull] IScopedInstance<ActionBindingContext> bindingContextAccessor,
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IUrlHelper urlHelper)
[NotNull] IUrlHelper urlHelper,
[NotNull] IHtmlEncoder htmlEncoder)
{
_antiForgery = antiForgery;
_bindingContextAccessor = bindingContextAccessor;
_metadataProvider = metadataProvider;
_urlHelper = urlHelper;
_htmlEncoder = htmlEncoder;
// Underscores are fine characters in id's.
IdAttributeDotReplacement = "_";
@ -50,13 +53,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <inheritdoc />
public string Encode(string value)
{
return !string.IsNullOrEmpty(value) ? WebUtility.HtmlEncode(value) : string.Empty;
return !string.IsNullOrEmpty(value) ? _htmlEncoder.HtmlEncode(value) : string.Empty;
}
/// <inheritdoc />
public string Encode(object value)
{
return (value != null) ? WebUtility.HtmlEncode(value.ToString()) : string.Empty;
return (value != null) ? _htmlEncoder.HtmlEncode(value.ToString()) : string.Empty;
}
/// <inheritdoc />
@ -138,7 +141,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
ModelExplorer modelExplorer,
string expression)
{
var tagBuilder = new TagBuilder("input");
var tagBuilder = new TagBuilder("input", _htmlEncoder);
tagBuilder.MergeAttribute("type", GetInputTypeString(InputType.Hidden));
tagBuilder.MergeAttribute("value", "false");
@ -252,7 +255,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
return null;
}
var tagBuilder = new TagBuilder("label");
var tagBuilder = new TagBuilder("label", _htmlEncoder);
var idString =
TagBuilder.CreateSanitizedId(GetFullHtmlFieldName(viewContext, expression), IdAttributeDotReplacement);
tagBuilder.Attributes.Add("for", idString);
@ -454,7 +457,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
// Convert each ListItem to an <option> tag and wrap them with <optgroup> if requested.
var listItemBuilder = GenerateGroupsAndOptions(optionLabel, selectList);
var tagBuilder = new TagBuilder("select")
var tagBuilder = new TagBuilder("select", _htmlEncoder)
{
InnerHtml = listItemBuilder.ToString()
};
@ -521,7 +524,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
value = modelExplorer.Model.ToString();
}
var tagBuilder = new TagBuilder("textarea");
var tagBuilder = new TagBuilder("textarea", _htmlEncoder);
tagBuilder.GenerateId(fullName, IdAttributeDotReplacement);
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes), true);
if (rows > 0)
@ -545,7 +548,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
// The first newline is always trimmed when a TextArea is rendered, so we add an extra one
// in case the value being rendered is something like "\r\nHello".
tagBuilder.InnerHtml = Environment.NewLine + WebUtility.HtmlEncode(value);
tagBuilder.InnerHtml = Environment.NewLine + _htmlEncoder.HtmlEncode(value);
return tagBuilder;
}
@ -615,7 +618,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
{
tag = viewContext.ValidationMessageElement;
}
var tagBuilder = new TagBuilder(tag);
var tagBuilder = new TagBuilder(tag, _htmlEncoder);
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
// Only the style of the span is changed according to the errors if message is null or empty.
@ -668,7 +671,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
{
headerTag = viewContext.ValidationSummaryMessageElement;
}
var messageTag = new TagBuilder(headerTag);
var messageTag = new TagBuilder(headerTag, _htmlEncoder);
messageTag.SetInnerText(message);
wrappedMessage = messageTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
}
@ -690,7 +693,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
if (!string.IsNullOrEmpty(errorText))
{
var listItem = new TagBuilder("li");
var listItem = new TagBuilder("li", _htmlEncoder);
listItem.SetInnerText(errorText);
htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
}
@ -702,12 +705,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
htmlSummary.AppendLine(HiddenListItem);
}
var unorderedList = new TagBuilder("ul")
var unorderedList = new TagBuilder("ul", _htmlEncoder)
{
InnerHtml = htmlSummary.ToString()
};
var tagBuilder = new TagBuilder("div");
var tagBuilder = new TagBuilder("div", _htmlEncoder);
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
if (viewContext.ViewData.ModelState.IsValid)
@ -758,9 +761,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <remarks>
/// Not used directly in HtmlHelper. Exposed for use in DefaultDisplayTemplates.
/// </remarks>
internal static TagBuilder GenerateOption(SelectListItem item, string encodedText)
internal static TagBuilder GenerateOption(SelectListItem item, string encodedText, IHtmlEncoder htmlEncoder)
{
var tagBuilder = new TagBuilder("option")
var tagBuilder = new TagBuilder("option", htmlEncoder)
{
InnerHtml = encodedText,
};
@ -819,7 +822,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
string method,
object htmlAttributes)
{
var tagBuilder = new TagBuilder("form");
var tagBuilder = new TagBuilder("form", _htmlEncoder);
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
// action is implicitly generated from other parameters, so htmlAttributes take precedence.
@ -860,7 +863,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(expression));
}
var tagBuilder = new TagBuilder("input");
var tagBuilder = new TagBuilder("input", _htmlEncoder);
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("type", GetInputTypeString(inputType));
tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);
@ -945,9 +948,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
[NotNull] string url,
object htmlAttributes)
{
var tagBuilder = new TagBuilder("a")
var tagBuilder = new TagBuilder("a", _htmlEncoder)
{
InnerHtml = WebUtility.HtmlEncode(linkText),
InnerHtml = _htmlEncoder.HtmlEncode(linkText),
};
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
@ -1127,7 +1130,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
TagBuilder groupBuilder = null;
if (optGroup != null)
{
groupBuilder = new TagBuilder("optgroup");
groupBuilder = new TagBuilder("optgroup", _htmlEncoder);
if (optGroup.Name != null)
{
groupBuilder.MergeAttribute("label", optGroup.Name);
@ -1158,7 +1161,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
private string GenerateOption(SelectListItem item)
{
var encodedText = Encode(item.Text);
var tagBuilder = GenerateOption(item, encodedText);
var tagBuilder = GenerateOption(item, encodedText, _htmlEncoder);
return tagBuilder.ToString(TagRenderMode.Normal);
}

View File

@ -11,6 +11,7 @@ using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering.Expressions;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc.Rendering
{
@ -37,11 +38,17 @@ namespace Microsoft.AspNet.Mvc.Rendering
public HtmlHelper(
[NotNull] IHtmlGenerator htmlGenerator,
[NotNull] ICompositeViewEngine viewEngine,
[NotNull] IModelMetadataProvider metadataProvider)
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IHtmlEncoder htmlEncoder,
[NotNull] IUrlEncoder urlEncoder,
[NotNull] IJavaScriptStringEncoder javaScriptStringEncoder)
{
_viewEngine = viewEngine;
_htmlGenerator = htmlGenerator;
MetadataProvider = metadataProvider;
HtmlEncoder = htmlEncoder;
UrlEncoder = urlEncoder;
JavaScriptStringEncoder = javaScriptStringEncoder;
}
/// <inheritdoc />
@ -107,7 +114,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
/// <inheritdoc />
public IModelMetadataProvider MetadataProvider { get; private set; }
public IHtmlEncoder HtmlEncoder { get; }
/// <inheritdoc />
public IUrlEncoder UrlEncoder { get; }
/// <inheritdoc />
public IJavaScriptStringEncoder JavaScriptStringEncoder { get; }
/// <inheritdoc />
public IModelMetadataProvider MetadataProvider { get; }
/// <summary>
/// Creates a dictionary from an object, by adding each public instance property as a key with its associated

View File

@ -8,6 +8,7 @@ using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering.Expressions;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc.Rendering
{
@ -19,8 +20,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
public HtmlHelper(
[NotNull] IHtmlGenerator htmlGenerator,
[NotNull] ICompositeViewEngine viewEngine,
[NotNull] IModelMetadataProvider metadataProvider)
: base(htmlGenerator, viewEngine, metadataProvider)
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IHtmlEncoder htmlEncoder,
[NotNull] IUrlEncoder urlEncoder,
[NotNull] IJavaScriptStringEncoder javaScriptStringEncoder)
: base(htmlGenerator, viewEngine, metadataProvider, htmlEncoder, urlEncoder, javaScriptStringEncoder)
{
}

View File

@ -4,18 +4,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.IO;
using System.Text;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc.Rendering
{
public class TagBuilder
{
private string _innerHtml;
private readonly IHtmlEncoder _htmlEncoder;
public TagBuilder(string tagName)
: this(tagName, HtmlEncoder.Default)
{
}
public TagBuilder(string tagName, [NotNull] IHtmlEncoder htmlEncoder)
{
if (string.IsNullOrEmpty(tagName))
{
@ -24,6 +31,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
TagName = tagName;
Attributes = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
_htmlEncoder = htmlEncoder;
}
public IDictionary<string, string> Attributes { get; private set; }
@ -106,7 +114,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
}
private void AppendAttributes(StringBuilder sb)
private void AppendAttributes(TextWriter textWriter)
{
foreach (var attribute in Attributes)
{
@ -117,12 +125,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
continue;
}
var value = WebUtility.HtmlEncode(attribute.Value);
sb.Append(' ')
.Append(key)
.Append("=\"")
.Append(value)
.Append('"');
textWriter.Write(' ');
textWriter.Write(key);
textWriter.Write("=\"");
_htmlEncoder.HtmlEncode(attribute.Value, textWriter);
textWriter.Write('"');
}
}
@ -164,7 +171,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void SetInnerText(string innerText)
{
InnerHtml = WebUtility.HtmlEncode(innerText);
InnerHtml = _htmlEncoder.HtmlEncode(innerText);
}
public HtmlString ToHtmlString(TagRenderMode renderMode)
@ -179,39 +186,41 @@ namespace Microsoft.AspNet.Mvc.Rendering
public string ToString(TagRenderMode renderMode)
{
var sb = new StringBuilder();
switch (renderMode)
using (var stringWriter = new StringWriter())
{
case TagRenderMode.StartTag:
sb.Append('<')
.Append(TagName);
AppendAttributes(sb);
sb.Append('>');
break;
case TagRenderMode.EndTag:
sb.Append("</")
.Append(TagName)
.Append('>');
break;
case TagRenderMode.SelfClosing:
sb.Append('<')
.Append(TagName);
AppendAttributes(sb);
sb.Append(" />");
break;
default:
sb.Append('<')
.Append(TagName);
AppendAttributes(sb);
sb.Append('>')
.Append(InnerHtml)
.Append("</")
.Append(TagName)
.Append('>');
break;
}
switch (renderMode)
{
case TagRenderMode.StartTag:
stringWriter.Write('<');
stringWriter.Write(TagName);
AppendAttributes(stringWriter);
stringWriter.Write('>');
break;
case TagRenderMode.EndTag:
stringWriter.Write("</");
stringWriter.Write(TagName);
stringWriter.Write('>');
break;
case TagRenderMode.SelfClosing:
stringWriter.Write('<');
stringWriter.Write(TagName);
AppendAttributes(stringWriter);
stringWriter.Write(" />");
break;
default:
stringWriter.Write('<');
stringWriter.Write(TagName);
AppendAttributes(stringWriter);
stringWriter.Write('>');
stringWriter.Write(InnerHtml);
stringWriter.Write("</");
stringWriter.Write(TagName);
stringWriter.Write('>');
break;
}
return sb.ToString();
return stringWriter.ToString();
}
}
private static class Html401IdUtil

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc.Rendering
{
@ -45,6 +46,21 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// </summary>
ViewDataDictionary ViewData { get; }
/// <summary>
/// Gets the <see cref="IHtmlEncoder"/> to be used for encoding HTML.
/// </summary>
IHtmlEncoder HtmlEncoder { get; }
/// <summary>
/// Gets the <see cref="IUrlEncoder"/> to be used for encoding a URL.
/// </summary>
IUrlEncoder UrlEncoder { get; }
/// <summary>
/// Gets the <see cref="IJavaScriptStringEncoder"/> to be used for encoding JavaScript.
/// </summary>
IJavaScriptStringEncoder JavaScriptStringEncoder { get; }
/// <summary>
/// Returns an anchor (&lt;a&gt;) element that contains a URL path to the specified action.
/// </summary>

View File

@ -100,6 +100,7 @@ namespace Microsoft.AspNet.Mvc.Razor
CreateTagHelperMethodName = "CreateTagHelper",
StartWritingScopeMethodName = "StartWritingScope",
EndWritingScopeMethodName = "EndWritingScope",
HtmlEncoderPropertyName = "HtmlEncoder",
})
{
ResolveUrlMethodName = "Href",

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
@ -14,6 +13,7 @@ using Microsoft.AspNet.PageExecutionInstrumentation;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
namespace Microsoft.AspNet.Mvc.Razor
{
@ -61,6 +61,12 @@ namespace Microsoft.AspNet.Mvc.Razor
/// <inheritdoc />
public bool IsPartial { get; set; }
/// <summary>
/// Gets the <see cref="IHtmlEncoder"/> to be used for encoding HTML.
/// </summary>
[Activate]
public IHtmlEncoder HtmlEncoder { get; set; }
/// <inheritdoc />
public IPageExecutionContext PageExecutionContext { get; set; }
@ -264,7 +270,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{
if (!string.IsNullOrEmpty(value))
{
writer.Write(WebUtility.HtmlEncode(value));
HtmlEncoder.HtmlEncode(value, writer);
}
}

View File

@ -2,10 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Mvc.TagHelpers.Internal;
@ -152,6 +150,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
[Activate]
protected internal IMemoryCache Cache { get; set; }
[Activate]
protected internal IHtmlEncoder HtmlEncoder { get; set; }
// Internal for ease of use when testing.
protected internal GlobbingUrlBuilder GlobbingUrlBuilder { get; set; }
@ -207,7 +208,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
foreach (var url in urls)
{
attributes["href"] = WebUtility.HtmlEncode(url);
attributes["href"] = HtmlEncoder.HtmlEncode(url);
BuildLinkTag(attributes, builder);
}
}
@ -225,7 +226,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
builder.AppendFormat(
CultureInfo.InvariantCulture,
"<meta name=\"x-stylesheet-fallback-test\" class=\"{0}\" />",
WebUtility.HtmlEncode(FallbackTestClass));
HtmlEncoder.HtmlEncode(FallbackTestClass));
// Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra
// <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false,

View File

@ -3,10 +3,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting;
@ -135,6 +133,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Internal for ease of use when testing.
protected internal GlobbingUrlBuilder GlobbingUrlBuilder { get; set; }
[Activate]
protected internal IHtmlEncoder HtmlEncoder { get; set; }
/// <inheritdoc />
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
@ -191,7 +192,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
foreach (var url in urls)
{
attributes["src"] = WebUtility.HtmlEncode(url);
attributes["src"] = HtmlEncoder.HtmlEncode(url);
var content = string.Equals(url, staticSrc, StringComparison.OrdinalIgnoreCase)
? originalContent
: string.Empty;
@ -283,7 +284,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
content.Append(" ")
.Append(srcKey)
.Append("=\\\"")
.Append(WebUtility.HtmlEncode(srcValue))
.Append(HtmlEncoder.HtmlEncode(srcValue))
.Append("\\\"");
}
}

View File

@ -134,6 +134,7 @@ namespace Microsoft.Framework.DependencyInjection
services.AddDataProtection(configuration);
services.AddRouting(configuration);
services.AddAuthorization(configuration);
services.AddWebEncoders();
services.Configure<RouteOptions>(routeOptions =>
routeOptions.ConstraintMap
.Add("exists",

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Core.Collections;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -34,7 +35,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
serializer: null,
tokenStore: null,
generator: null,
validator: null);
validator: null,
htmlEncoder: new HtmlEncoder());
// Act & assert
var ex =
@ -65,7 +67,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
serializer: null,
tokenStore: null,
generator: null,
validator: null);
validator: null,
htmlEncoder: new HtmlEncoder());
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(
@ -94,7 +97,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
serializer: null,
tokenStore: null,
generator: null,
validator: null);
validator: null,
htmlEncoder: new HtmlEncoder());
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => worker.GetFormInputElement(mockHttpContext.Object));
@ -122,7 +126,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
serializer: null,
tokenStore: null,
generator: null,
validator: null);
validator: null,
htmlEncoder: new HtmlEncoder());
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => worker.GetTokens(mockHttpContext.Object, "cookie-token"));
@ -409,7 +414,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
serializer: context.TokenSerializer != null ? context.TokenSerializer.Object : null,
tokenStore: context.TokenStore != null ? context.TokenStore.Object : null,
generator: context.TokenProvider != null ? context.TokenProvider.Object : null,
validator: context.TokenProvider != null ? context.TokenProvider.Object : null);
validator: context.TokenProvider != null ? context.TokenProvider.Object : null,
htmlEncoder: new HtmlEncoder());
}
private Mock<HttpContext> GetHttpContext(bool setupResponse = true)

View File

@ -5,6 +5,7 @@ using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -39,7 +40,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
return new AntiForgery(claimExtractor.Object,
dataProtectionProvider.Object,
additionalDataProvider.Object,
optionsAccessor.Object);
optionsAccessor.Object,
new HtmlEncoder());
}
}
}

View File

@ -29,17 +29,17 @@ namespace Microsoft.AspNet.Mvc.Core
{ "<blink>text</blink>", false, "<blink>text</blink>" },
{ "<blink>text</blink>", true, "&lt;blink&gt;text&lt;/blink&gt;" },
{ "&'\"", false, "&'\"" },
{ "&'\"", true, "&amp;&#39;&quot;" },
{ "&'\"", true, "&amp;&#x27;&quot;" },
{ " ¡ÿĀ", false, " ¡ÿĀ" }, // high ASCII
{ " ¡ÿĀ", true, "&#160;&#161;&#255;Ā" },
{ " ¡ÿĀ", true, "&#xA0;&#xA1;&#xFF;&#x100;" },
{ "Chinese西雅图Chars", false, "Chinese西雅图Chars" },
{ "Chinese西雅图Chars", true, "Chinese西雅图Chars" },
{ "Chinese西雅图Chars", true, "Chinese&#x897F;&#x96C5;&#x56FE;Chars" },
{ "Unicode؃Format؃Char", false, "Unicode؃Format؃Char" }, // class Cf
{ "Unicode؃Format؃Char", true, "Unicode؃Format؃Char" },
{ "Unicode؃Format؃Char", true, "Unicode&#x603;Format&#x603;Char" },
{ "UnicodeῼTitlecaseῼChar", false, "UnicodeῼTitlecaseῼChar" }, // class Lt
{ "UnicodeῼTitlecaseῼChar", true, "UnicodeῼTitlecaseῼChar" },
{ "UnicodeῼTitlecaseῼChar", true, "Unicode&#x1FFC;Titlecase&#x1FFC;Char" },
{ "UnicodeCombiningChar", false, "UnicodeCombiningChar" }, // class Mc
{ "UnicodeCombiningChar", true, "UnicodeCombiningChar" },
{ "UnicodeCombiningChar", true, "Unicode&#x903;Combining&#x903;Char" },
};
}
}

View File

@ -12,6 +12,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Testing;
using Microsoft.Framework.Internal;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -527,8 +528,8 @@ Environment.NewLine;
// DateTime-local is not special-cased unless using Html5DateRenderingMode.Rfc3339.
[Theory]
[InlineData("date", "{0:d}", "02/01/2000")]
[InlineData("datetime", null, "02/01/2000 03:04:05 +00:00")]
[InlineData("datetime-local", null, "02/01/2000 03:04:05 +00:00")]
[InlineData("datetime", null, "02/01/2000 03:04:05 &#x2B;00:00")]
[InlineData("datetime-local", null, "02/01/2000 03:04:05 &#x2B;00:00")]
[InlineData("time", "{0:t}", "03:04")]
[ReplaceCulture]
public void Editor_FindsCorrectDateOrTimeTemplate(string dataTypeName, string editFormatString, string expected)
@ -564,7 +565,7 @@ Environment.NewLine;
[Theory]
[InlineData("date", "{0:d}", "2000-01-02")]
[InlineData("datetime", null, "2000-01-02T03:04:05.060+00:00")]
[InlineData("datetime", null, "2000-01-02T03:04:05.060&#x2B;00:00")]
[InlineData("datetime-local", null, "2000-01-02T03:04:05.060")]
[InlineData("time", "{0:t}", "03:04:05.060")]
[ReplaceCulture]
@ -615,7 +616,7 @@ Environment.NewLine;
{
// Arrange
var expectedInput = "<input class=\"text-box single-line\" id=\"FieldPrefix\" name=\"FieldPrefix\" type=\"" +
dataTypeName + "\" value=\"Formatted as 2000-01-02T03:04:05.0600000+00:00\" />";
dataTypeName + "\" value=\"Formatted as 2000-01-02T03:04:05.0600000&#x2B;00:00\" />";
var offset = TimeSpan.FromHours(0);
var model = new DateTimeOffset(
year: 2000,
@ -808,6 +809,21 @@ Environment.NewLine;
get { return _innerHelper.ViewData; }
}
public IHtmlEncoder HtmlEncoder
{
get { return _innerHelper.HtmlEncoder; }
}
public IUrlEncoder UrlEncoder
{
get { return _innerHelper.UrlEncoder; }
}
public IJavaScriptStringEncoder JavaScriptStringEncoder
{
get { return _innerHelper.JavaScriptStringEncoder; }
}
public void Contextualize([NotNull] ViewContext viewContext)
{
(_innerHelper as ICanHasViewContext)?.Contextualize(viewContext);

View File

@ -12,6 +12,7 @@ using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
using Moq;
namespace Microsoft.AspNet.Mvc.Rendering
@ -191,11 +192,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
GetAntiForgeryInstance(),
bindingContextAccessor,
provider,
urlHelper);
urlHelper,
new HtmlEncoder());
}
// TemplateRenderer will Contextualize this transient service.
var innerHelper = (IHtmlHelper)new HtmlHelper(htmlGenerator, viewEngine, provider);
var innerHelper = (IHtmlHelper)new HtmlHelper(
htmlGenerator,
viewEngine,
provider,
new HtmlEncoder(),
new UrlEncoder(),
new JavaScriptStringEncoder());
if (innerHelperWrapper != null)
{
innerHelper = innerHelperWrapper(innerHelper);
@ -204,7 +212,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
.Setup(s => s.GetService(typeof(IHtmlHelper)))
.Returns(() => innerHelper);
var htmlHelper = new HtmlHelper<TModel>(htmlGenerator, viewEngine, provider);
var htmlHelper = new HtmlHelper<TModel>(
htmlGenerator,
viewEngine,
provider,
new HtmlEncoder(),
new UrlEncoder(),
new JavaScriptStringEncoder());
var viewContext = new ViewContext(actionContext, Mock.Of<IView>(), viewData, new StringWriter());
htmlHelper.Contextualize(viewContext);
@ -244,21 +258,24 @@ namespace Microsoft.AspNet.Mvc.Rendering
var additionalDataProvider = new Mock<IAntiForgeryAdditionalDataProvider>();
var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options).Returns(new MvcOptions());
return new AntiForgery(claimExtractor.Object,
dataProtectionProvider.Object,
additionalDataProvider.Object,
optionsAccessor.Object);
return new AntiForgery(
claimExtractor.Object,
dataProtectionProvider.Object,
additionalDataProvider.Object,
optionsAccessor.Object,
new HtmlEncoder());
}
private static string FormatOutput(ModelExplorer modelExplorer)
{
var metadata = modelExplorer.Metadata;
return string.Format(CultureInfo.InvariantCulture,
"Model = {0}, ModelType = {1}, PropertyName = {2}, SimpleDisplayText = {3}",
modelExplorer.Model ?? "(null)",
metadata.ModelType == null ? "(null)" : metadata.ModelType.FullName,
metadata.PropertyName ?? "(null)",
modelExplorer.GetSimpleDisplayText() ?? "(null)");
return string.Format(
CultureInfo.InvariantCulture,
"Model = {0}, ModelType = {1}, PropertyName = {2}, SimpleDisplayText = {3}",
modelExplorer.Model ?? "(null)",
metadata.ModelType == null ? "(null)" : metadata.ModelType.FullName,
metadata.PropertyName ?? "(null)",
modelExplorer.GetSimpleDisplayText() ?? "(null)");
}
private static IUrlHelper CreateUrlHelper()

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -275,7 +276,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void BeginFormWithNoParameters_CallsHtmlGeneratorWithExpectedValues()
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -309,7 +310,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void BeginFormWithMethodParameter_CallsHtmlGeneratorWithExpectedValues(FormMethod method)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -345,7 +346,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
object htmlAttributes)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -379,7 +380,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void BeginFormWithRouteValuesParameter_CallsHtmlGeneratorWithExpectedValues(object routeValues)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -415,7 +416,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
string controllerName)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -452,7 +453,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
object routeValues)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -489,7 +490,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
FormMethod method)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -527,7 +528,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
FormMethod method)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -565,7 +566,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
object htmlAttributes)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -599,7 +600,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void BeginRouteFormWithRouteValuesParameter_CallsHtmlGeneratorWithExpectedValues(object routeValues)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -632,7 +633,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void BeginRouteFormWithRouteNameParameter_CallsHtmlGeneratorWithExpectedValues(string routeName)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -667,7 +668,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
object routeValues)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -702,7 +703,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
FormMethod method)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -738,7 +739,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
FormMethod method)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator
@ -774,7 +775,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
object htmlAttributes)
{
// Arrange
var tagBuilder = new TagBuilder(tagName: "form");
var tagBuilder = new TagBuilder(tagName: "form", htmlEncoder: new HtmlEncoder());
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(htmlGenerator.Object);
htmlGenerator

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.WebEncoders;
using Xunit;
namespace Microsoft.AspNet.Mvc.Core.Rendering
@ -28,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.Core.Rendering
public void MergeAttribute_IgnoresCase(bool replaceExisting, string expectedKey, string expectedValue)
{
// Arrange
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
tagBuilder.Attributes.Add("Hello", "World");
// Act
@ -43,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.Core.Rendering
public void AddCssClass_IgnoresCase()
{
// Arrange
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
tagBuilder.Attributes.Add("ClaSs", "btn");
// Act
@ -58,7 +59,7 @@ namespace Microsoft.AspNet.Mvc.Core.Rendering
public void GenerateId_IgnoresCase()
{
// Arrange
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
tagBuilder.Attributes.Add("ID", "something");
// Act
@ -69,11 +70,12 @@ namespace Microsoft.AspNet.Mvc.Core.Rendering
Assert.Equal(new KeyValuePair<string, string>("ID", "something"), attribute);
}
[Theory]
[MemberData(nameof(RenderingTestingData))]
public void ToString_IgnoresIdAttributeCase(TagRenderMode renderingMode, string expectedOutput)
{
// Arrange
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
// An empty value id attribute should not be rendered via ToString.
tagBuilder.Attributes.Add("ID", string.Empty);
@ -85,11 +87,12 @@ namespace Microsoft.AspNet.Mvc.Core.Rendering
Assert.Equal(expectedOutput, value);
}
[Theory]
[MemberData(nameof(RenderingTestingData))]
public void ToHtmlString_IgnoresIdAttributeCase(TagRenderMode renderingMode, string expectedOutput)
{
// Arrange
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
// An empty value id attribute should not be rendered via ToHtmlString.
tagBuilder.Attributes.Add("ID", string.Empty);

View File

@ -1,9 +1,9 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Net;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.WebEncoders;
using Xunit;
namespace Microsoft.AspNet.Mvc
@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Mvc
// Arrange
var viewComponent = new TestViewComponent();
var expectedContent = "TestContent&";
var expectedEncodedContent = new HtmlString(WebUtility.HtmlEncode(expectedContent));
var expectedEncodedContent = new HtmlString(new HtmlEncoder().HtmlEncode(expectedContent));
// Act
var actualResult = viewComponent.Content(expectedContent);

View File

@ -4,6 +4,6 @@
<title>Action Link with non unicode host</title>
</head>
<body>
<a href="http://ping&#252;ino/Home/ActionLinkView">Ping&#252;ino</a>
<a href="http://ping&#xFC;ino/Home/ActionLinkView">Ping&#xFC;ino</a>
</body>
</html>

View File

@ -1,7 +1,7 @@
<div class="left">
<form action="/vehicles/42/edit" method="post"><div class="validation-summary-errors" data-valmsg-summary="true"><ul><li>The field Vin must be a string with a maximum length of 8.</li>
<li>The field Year must be between 1980 and 2034.</li>
<li>The field InspectedDates must be a string or array type with a maximum length of &#39;10&#39;.</li>
<li>The field InspectedDates must be a string or array type with a maximum length of &#x27;10&#x27;.</li>
</ul></div><div class="editor-label"><label for="Model">Model</label></div>
<div class="editor-field"><input class="text-box single-line" id="Model" name="Model" type="text" value="the Fastener" /> <span class="field-validation-valid" data-valmsg-for="Model" data-valmsg-replace="true"></span></div>
<div class="editor-label"><label for="Make">Make</label></div>

View File

@ -14,7 +14,7 @@
<label for="InspectedDates">InspectedDates</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="InspectedDates_0_" name="InspectedDates[0]" type="datetime" value="01/04/2001 00:00:00 -08:00" /><input class="text-box single-line" id="InspectedDates_1_" name="InspectedDates[1]" type="datetime" value="01/01/0001 00:00:00 +00:00" />
<input class="text-box single-line" id="InspectedDates_0_" name="InspectedDates[0]" type="datetime" value="01/04/2001 00:00:00 -08:00" /><input class="text-box single-line" id="InspectedDates_1_" name="InspectedDates[1]" type="datetime" value="01/01/0001 00:00:00 &#x2B;00:00" />
</div>
<input type="submit" value="Update" />
</form></div>

View File

@ -5,7 +5,7 @@
<body>
<form action="/MvcTagHelper_Home/CreateWarehouse" method="post"> <div>
<label class="warehouse" for="City">City</label>
<input size="50" type="text" data-val="true" data-val-minlength="The field City must be a string or array type with a minimum length of &#39;2&#39;." data-val-minlength-min="2" id="City" name="City" value="" />
<input size="50" type="text" data-val="true" data-val-minlength="The field City must be a string or array type with a minimum length of &#x27;2&#x27;." data-val-minlength-min="2" id="City" name="City" value="" />
<span class="field-validation-valid" data-valmsg-for="City" data-valmsg-replace="true"></span>
</div>
<div>

View File

@ -6,7 +6,7 @@
<form action="/MvcTagHelper_Home/EditWarehouse" method="post">
<div>
City_1
<input type="text" data-val="true" data-val-minlength="The field City must be a string or array type with a minimum length of &#39;2&#39;." data-val-minlength-min="2" id="City" name="City" value="City_1" />
<input type="text" data-val="true" data-val-minlength="The field City must be a string or array type with a minimum length of &#x27;2&#x27;." data-val-minlength-min="2" id="City" name="City" value="City_1" />
</div>
<div>
<label>Address</label>

View File

@ -19,7 +19,7 @@
<hr />
<div class="text-danger validation-summary-errors" data-valmsg-summary="true">
<ul><li>The field Age must be between 10 and 100.</li>
<li>The value &#39;z&#39; is not valid for Salary.</li>
<li>The value &#x27;z&#x27; is not valid for Salary.</li>
<li>The JoinDate field is required.</li>
</ul></div>
<div class="form-group">
@ -55,7 +55,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="JoinDate">JoinDate</label>
<div class="col-md-10">
<input class="form-control input-validation-error" type="date" data-val="true" data-val-required="The JoinDate field is required." id="JoinDate" name="JoinDate" value="01/01/0001 00:00:00 +00:00" />
<input class="form-control input-validation-error" type="date" data-val="true" data-val-required="The JoinDate field is required." id="JoinDate" name="JoinDate" value="01/01/0001 00:00:00 &#x2B;00:00" />
<span class="field-validation-error" data-valmsg-for="JoinDate" data-valmsg-replace="true">The JoinDate field is required.</span>
</div>
</div>
@ -63,7 +63,7 @@
<label class="control-label col-md-2" for="Salary">Salary</label>
<div class="col-md-10">
<input class="form-control input-validation-error" type="number" id="Salary" name="Salary" value="z" />
<span class="field-validation-error" data-valmsg-for="Salary" data-valmsg-replace="true">The value &#39;z&#39; is not valid for Salary.</span>
<span class="field-validation-error" data-valmsg-for="Salary" data-valmsg-replace="true">The value &#x27;z&#x27; is not valid for Salary.</span>
</div>
</div>

View File

@ -11,24 +11,9 @@
</head>
<body>
<h1 style="font-family: cursive;">ASP.NET vNext - About</h1>
<p>| <a href="/" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My Help</a> |</p>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div>

View File

@ -11,24 +11,9 @@
</head>
<body>
<h1 style="font-family: cursive;">ASP.NET vNext - Help</h1>
<p>| <a href="/" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My Help</a> |</p>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div>

View File

@ -18,24 +18,9 @@
</head>
<body>
<h1 style="font-family: cursive;">ASP.NET vNext - Home Page</h1>
<p>| <a href="/" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;">My Help</a> |</p>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div>
@ -43,8 +28,7 @@
<div>
<p>This website has <strong style="font-size: 1.25em;
text-decoration: underline;">not</strong> been approved yet. Visit <strong><a target="_blank" href="http://www.contoso.com">www.contoso.com</a></strong> for <strong>more</strong> information.</p>
<p>This website has <strong style="font-size: 1.25em;text-decoration: underline;">not</strong> been approved yet. Visit <strong><a target="_blank" href="http://www.contoso.com">www.contoso.com</a></strong> for <strong>more</strong> information.</p>
</div>
<div>

View File

@ -41,7 +41,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="UserId1">UserId1</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#39;UserId1&#39; is invalid." data-val-remote-additionalfields="*.UserId1" data-val-remote-url="/Aria/RemoteAttribute_Verify/IsIdAvailable" id="UserId1" name="UserId1" type="text" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#x27;UserId1&#x27; is invalid." data-val-remote-additionalfields="*.UserId1" data-val-remote-url="/Aria/RemoteAttribute_Verify/IsIdAvailable" id="UserId1" name="UserId1" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="UserId1" data-valmsg-replace="true"></span>
</div>
</div>
@ -49,7 +49,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="UserId2">UserId2</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#39;UserId2&#39; is invalid." data-val-remote-additionalfields="*.UserId2" data-val-remote-type="Post" data-val-remote-url="/RemoteAttribute_Verify/IsIdAvailable" id="UserId2" name="UserId2" type="text" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#x27;UserId2&#x27; is invalid." data-val-remote-additionalfields="*.UserId2" data-val-remote-type="Post" data-val-remote-url="/RemoteAttribute_Verify/IsIdAvailable" id="UserId2" name="UserId2" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="UserId2" data-valmsg-replace="true"></span>
</div>
</div>
@ -65,7 +65,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="UserId4">UserId4</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#39;UserId4&#39; is invalid." data-val-remote-additionalfields="*.UserId4,*.UserId1,*.UserId2,*.UserId3" data-val-remote-url="/AnotherAria/RemoteAttribute_Verify/IsIdAvailable" id="UserId4" name="UserId4" type="text" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#x27;UserId4&#x27; is invalid." data-val-remote-additionalfields="*.UserId4,*.UserId1,*.UserId2,*.UserId3" data-val-remote-url="/AnotherAria/RemoteAttribute_Verify/IsIdAvailable" id="UserId4" name="UserId4" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="UserId4" data-valmsg-replace="true"></span>
</div>
</div>

View File

@ -41,7 +41,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="UserId1">UserId1</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#39;UserId1&#39; is invalid." data-val-remote-additionalfields="*.UserId1" data-val-remote-url="/RemoteAttribute_Verify/IsIdAvailable" id="UserId1" name="UserId1" type="text" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#x27;UserId1&#x27; is invalid." data-val-remote-additionalfields="*.UserId1" data-val-remote-url="/RemoteAttribute_Verify/IsIdAvailable" id="UserId1" name="UserId1" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="UserId1" data-valmsg-replace="true"></span>
</div>
</div>
@ -49,7 +49,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="UserId2">UserId2</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#39;UserId2&#39; is invalid." data-val-remote-additionalfields="*.UserId2" data-val-remote-type="Post" data-val-remote-url="/RemoteAttribute_Verify/IsIdAvailable" id="UserId2" name="UserId2" type="text" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#x27;UserId2&#x27; is invalid." data-val-remote-additionalfields="*.UserId2" data-val-remote-type="Post" data-val-remote-url="/RemoteAttribute_Verify/IsIdAvailable" id="UserId2" name="UserId2" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="UserId2" data-valmsg-replace="true"></span>
</div>
</div>
@ -65,7 +65,7 @@
<div class="form-group">
<label class="control-label col-md-2" for="UserId4">UserId4</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#39;UserId4&#39; is invalid." data-val-remote-additionalfields="*.UserId4,*.UserId1,*.UserId2,*.UserId3" data-val-remote-url="/AnotherAria/RemoteAttribute_Verify/IsIdAvailable" id="UserId4" name="UserId4" type="text" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-remote="&#x27;UserId4&#x27; is invalid." data-val-remote-additionalfields="*.UserId4,*.UserId1,*.UserId2,*.UserId3" data-val-remote-url="/AnotherAria/RemoteAttribute_Verify/IsIdAvailable" id="UserId4" name="UserId4" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="UserId4" data-valmsg-replace="true"></span>
</div>
</div>

View File

@ -22,7 +22,7 @@ namespace Asp
private System.IO.TextWriter __tagHelperStringValueBuffer = null;
#pragma warning restore 0414
private Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperRunner();
private Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = null;
private Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager = new Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperScopeManager();
private Microsoft.AspNet.Mvc.Razor.InputTestTagHelper __Microsoft_AspNet_Mvc_Razor_InputTestTagHelper = null;
#line hidden
@ -42,6 +42,7 @@ namespace Asp
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
__tagHelperRunner = __tagHelperRunner ?? new Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelperRunner(HtmlEncoder);
BeginContext(120, 2, true);
WriteLiteral("\r\n");
EndContext();

View File

@ -10,6 +10,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -26,11 +27,14 @@ namespace Microsoft.AspNet.Mvc.Razor
var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>();
var htmlEncoder = new HtmlEncoder();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
.Returns(myService);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
.Returns(helper);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlEncoder)))
.Returns(htmlEncoder);
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
@ -90,11 +94,14 @@ namespace Microsoft.AspNet.Mvc.Razor
var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>();
var htmlEncoder = new HtmlEncoder();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
.Returns(myService);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
.Returns(helper);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlEncoder)))
.Returns(htmlEncoder);
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
@ -124,11 +131,14 @@ namespace Microsoft.AspNet.Mvc.Razor
var instance = new TestRazorPage();
var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>();
var htmlEncoder = new HtmlEncoder();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
.Returns(myService);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
.Returns(helper);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlEncoder)))
.Returns(htmlEncoder);
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
@ -158,11 +168,14 @@ namespace Microsoft.AspNet.Mvc.Razor
var instance = new DoesNotDeriveFromRazorPageOfTButHasModelProperty();
var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>();
var htmlEncoder = new HtmlEncoder();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(MyService)))
.Returns(myService);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlHelper<object>)))
.Returns(helper);
serviceProvider.Setup(p => p.GetService(typeof(IHtmlEncoder)))
.Returns(htmlEncoder);
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);

View File

@ -10,6 +10,7 @@ using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.PageExecutionInstrumentation;
using Microsoft.AspNet.Testing;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -28,6 +29,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var viewContext = CreateViewContext();
var page = CreatePage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.Write("Hello Prefix");
v.StartWritingScope();
v.Write("Hello from Output");
@ -51,6 +53,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var viewContext = CreateViewContext();
var page = CreatePage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.Write("Hello Prefix");
v.StartWritingScope();
v.Write("Hello In Scope");
@ -73,6 +76,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var viewContext = CreateViewContext();
var page = CreatePage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.Write("Hello Prefix");
v.StartWritingScope();
v.Write("Hello In Scope Pre Nest");
@ -453,6 +457,7 @@ namespace Microsoft.AspNet.Mvc.Razor
.Verifiable();
var page = CreatePage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.Write(v.Href("url"));
});
var services = new Mock<IServiceProvider>();
@ -554,6 +559,7 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var page = CreatePage(p =>
{
p.HtmlEncoder = new HtmlEncoder();
p.WriteAttribute("href",
new PositionTagged<string>("prefix", 0),
new PositionTagged<string>("suffix", 34),

View File

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.PageExecutionInstrumentation;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -30,6 +31,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var page = new TestableRazorPage(v =>
{
actual = v.Output;
v.HtmlEncoder = new HtmlEncoder();
v.Write("Hello world");
});
var view = new RazorView(Mock.Of<IRazorViewEngine>(),
@ -165,17 +167,20 @@ namespace Microsoft.AspNet.Mvc.Razor
public async Task RenderAsync_AsPartial_ExecutesLayout_ButNotViewStartPages()
{
// Arrange
var expected = string.Join(Environment.NewLine,
var htmlEncoder = new HtmlEncoder();
var expected = string.Join(htmlEncoder.HtmlEncode(Environment.NewLine),
"layout-content",
"page-content");
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Layout = LayoutPath;
v.Write("page-content");
});
var layout = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Write("layout-content" + Environment.NewLine);
v.RenderBodyPublic();
});
@ -359,14 +364,19 @@ namespace Microsoft.AspNet.Mvc.Razor
public async Task RenderAsync_ExecutesLayoutPages()
{
// Arrange
var expected =
@"layout-content
head-content
body-content
foot-content";
var htmlEncoder = new HtmlEncoder();
var htmlEncodedNewLine = htmlEncoder.HtmlEncode(Environment.NewLine);
var expected = "layout-content" +
htmlEncodedNewLine +
"head-content" +
htmlEncodedNewLine +
"body-content" +
htmlEncodedNewLine +
"foot-content";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.WriteLiteral("body-content");
v.Layout = LayoutPath;
v.DefineSection("head", async writer =>
@ -380,6 +390,7 @@ foot-content";
});
var layout = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Write("layout-content" + Environment.NewLine);
v.Write(v.RenderSection("head"));
v.Write(Environment.NewLine);
@ -475,15 +486,21 @@ foot-content";
public async Task RenderAsync_ExecutesNestedLayoutPages()
{
// Arrange
var expected =
@"layout-2
bar-content
layout-1
foo-content
body-content";
var htmlEncoder = new HtmlEncoder();
var htmlEncodedNewLine = htmlEncoder.HtmlEncode(Environment.NewLine);
var expected = "layout-2" +
htmlEncodedNewLine +
"bar-content" +
Environment.NewLine +
"layout-1" +
htmlEncodedNewLine +
"foo-content" +
Environment.NewLine +
"body-content";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.DefineSection("foo", async writer =>
{
await writer.WriteLineAsync("foo-content");
@ -493,6 +510,7 @@ body-content";
});
var layout1 = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Write("layout-1" + Environment.NewLine);
v.Write(v.RenderSection("foo"));
v.DefineSection("bar", writer => writer.WriteLineAsync("bar-content"));
@ -501,6 +519,7 @@ body-content";
});
var layout2 = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Write("layout-2" + Environment.NewLine);
v.Write(v.RenderSection("bar"));
v.RenderBodyPublic();
@ -529,14 +548,18 @@ body-content";
public async Task RenderAsync_DoesNotCopyContentOnceRazorTextWriterIsNoLongerBuffering()
{
// Arrange
var expected =
@"layout-1
body content
section-content-1
section-content-2";
var htmlEncoder = new HtmlEncoder();
var expected = "layout-1" +
htmlEncoder.HtmlEncode(Environment.NewLine) +
"body content" +
Environment.NewLine +
"section-content-1" +
Environment.NewLine +
"section-content-2";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Layout = "layout-1";
v.WriteLiteral("body content" + Environment.NewLine);
v.DefineSection("foo", async _ =>
@ -549,6 +572,7 @@ section-content-2";
var layout1 = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Write("layout-1" + Environment.NewLine);
v.RenderBodyPublic();
v.Write(v.RenderSection("foo"));
@ -576,13 +600,16 @@ section-content-2";
public async Task FlushAsync_DoesNotThrowWhenInvokedInsideOfASection()
{
// Arrange
var expected =
@"layout-1
section-content-1
section-content-2";
var htmlEncoder = new HtmlEncoder();
var expected = "layout-1" +
htmlEncoder.HtmlEncode(Environment.NewLine) +
"section-content-1" +
Environment.NewLine +
"section-content-2";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Layout = "layout-1";
v.DefineSection("foo", async _ =>
{
@ -594,6 +621,7 @@ section-content-2";
var layout1 = new TestableRazorPage(v =>
{
v.HtmlEncoder = htmlEncoder;
v.Write("layout-1" + Environment.NewLine);
v.RenderBodyPublic();
v.Write(v.RenderSection("foo"));
@ -649,6 +677,7 @@ section-content-2";
var expected = @"A layout page cannot be rendered after 'FlushAsync' has been invoked.";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.DefineSection("foo", async writer =>
{
writer.WriteLine("foo-content");
@ -659,6 +688,7 @@ section-content-2";
});
var layoutPage = new TestableRazorPage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.Write("layout-1" + Environment.NewLine);
v.Write(v.RenderSection("foo"));
v.DefineSection("bar", writer => writer.WriteLineAsync("bar-content"));
@ -720,6 +750,7 @@ section-content-2";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
v.Layout = "Layout";
Assert.Same(pageWriter, v.Output);
Assert.Same(pageContext, v.PageExecutionContext);
@ -728,6 +759,7 @@ section-content-2";
var layout = new TestableRazorPage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
Assert.Same(layoutWriter, v.Output);
Assert.Same(layoutContext, v.PageExecutionContext);
v.RenderBodyPublic();
@ -779,6 +811,7 @@ section-content-2";
var page = new TestableRazorPage(v =>
{
v.HtmlEncoder = new HtmlEncoder();
Assert.IsType<RazorTextWriter>(v.Output);
Assert.Same(pageContext, v.PageExecutionContext);
executed = true;

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -41,7 +42,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "id", "myanchor" },
{ "asp-route-foo", "bar" },
})
},
htmlEncoder: new HtmlEncoder())
{
Content = "Something"
};
@ -88,7 +90,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(
"a",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
Content = string.Empty
};
@ -97,7 +100,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
generator
.Setup(mock => mock.GenerateRouteLink(
string.Empty, "Default", "http", "contoso.com", "hello=world", null, null))
.Returns(new TagBuilder("a"))
.Returns(new TagBuilder("a", new HtmlEncoder()))
.Verifiable();
var anchorTagHelper = new AnchorTagHelper
{
@ -127,7 +130,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(
"a",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
Content = string.Empty
};
@ -136,7 +140,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
generator
.Setup(mock => mock.GenerateActionLink(
string.Empty, "Index", "Home", "http", "contoso.com", "hello=world", null, null))
.Returns(new TagBuilder("a"))
.Returns(new TagBuilder("a", new HtmlEncoder()))
.Verifiable();
var anchorTagHelper = new AnchorTagHelper
{
@ -173,7 +177,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>()
{
{ "href", "http://www.contoso.com" }
});
},
htmlEncoder: new HtmlEncoder());
if (propertyName == "asp-route-")
{
output.Attributes.Add("asp-route-foo", "bar");
@ -208,7 +213,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
typeof(AnchorTagHelper).GetProperty(propertyName).SetValue(anchorTagHelper, "Home");
var output = new TagHelperOutput(
"a",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var expectedErrorMessage = "Cannot determine an 'href' attribute for <a>. An <a> with a specified " +
"'asp-route' must not have an 'asp-action' or 'asp-controller' attribute.";

View File

@ -17,6 +17,7 @@ using Microsoft.AspNet.Routing;
using Microsoft.Framework.Cache.Memory;
using Microsoft.Framework.Cache.Memory.Infrastructure;
using Microsoft.Framework.Expiration.Interfaces;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -244,7 +245,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var childContent = "original-child-content";
var cache = new MemoryCache(new MemoryCacheOptions());
var tagHelperContext1 = GetTagHelperContext(id, childContent);
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string>());
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string>(), new HtmlEncoder());
var cacheTagHelper1 = new CacheTagHelper
{
VaryByQuery = "key1,key2",
@ -265,7 +266,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange - 2
var tagHelperContext2 = GetTagHelperContext(id, "different-content");
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string>());
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string>(), new HtmlEncoder());
var cacheTagHelper2 = new CacheTagHelper
{
VaryByQuery = "key1,key2",
@ -293,7 +294,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var childContent1 = "original-child-content";
var cache = new MemoryCache(new MemoryCacheOptions());
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput1 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -318,7 +321,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange - 2
var childContent2 = "different-content";
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput2 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -529,7 +534,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
.Returns(() => currentTime);
var cache = new MemoryCache(new MemoryCacheOptions { Clock = clock.Object });
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput1 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -553,7 +560,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange - 2
var childContent2 = "different-content";
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput2 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -588,7 +597,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
.Returns(() => currentTime);
var cache = new MemoryCache(new MemoryCacheOptions { Clock = clock.Object });
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput1 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -613,7 +624,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
currentTime = currentTime.AddMinutes(5).AddSeconds(2);
var childContent2 = "different-content";
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput2 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -647,7 +660,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
.Returns(() => currentTime);
var cache = new MemoryCache(new MemoryCacheOptions { Clock = clock.Object });
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput1 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -672,7 +687,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
currentTime = currentTime.AddSeconds(35);
var childContent2 = "different-content";
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string> { { "attr", "value" } })
var tagHelperOutput2 = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"
@ -716,7 +733,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
});
return Task.FromResult(expectedContent);
});
var tagHelperOutput = new TagHelperOutput("cache", new Dictionary<string, string>())
var tagHelperOutput = new TagHelperOutput("cache",
new Dictionary<string, string> { { "attr", "value" } },
new HtmlEncoder())
{
PreContent = "<cache>",
PostContent = "</cache>"

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -145,7 +146,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers.Test
{
attributes = attributes ?? new Dictionary<string, string>();
return new TagHelperOutput(tagName, attributes);
return new TagHelperOutput(tagName, attributes, new HtmlEncoder());
}
}
}

View File

@ -10,6 +10,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -42,7 +43,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "id", "myform" },
{ "asp-route-foo", "bar" },
})
},
htmlEncoder: new HtmlEncoder())
{
PostContent = "Something"
};
@ -98,7 +100,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(
"form",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
generator
.Setup(mock => mock.GenerateForm(
@ -108,10 +111,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
It.IsAny<object>(),
It.IsAny<string>(),
It.IsAny<object>()))
.Returns(new TagBuilder("form"));
.Returns(new TagBuilder("form", new HtmlEncoder()));
generator.Setup(mock => mock.GenerateAntiForgery(viewContext))
.Returns(new TagBuilder("input"));
.Returns(new TagBuilder("input", new HtmlEncoder()));
var formTagHelper = new FormTagHelper
{
Action = "Index",
@ -149,7 +152,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "asp-route-val", "hello" },
{ "asp-roUte--Foo", "bar" }
});
},
htmlEncoder: new HtmlEncoder());
output.Attributes.Add(expectedAttribute);
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
@ -175,7 +179,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
routeValue = Assert.Single(routeValueDictionary, kvp => kvp.Key.Equals("-Foo"));
Assert.Equal("bar", routeValue.Value);
})
.Returns(new TagBuilder("form"))
.Returns(new TagBuilder("form", new HtmlEncoder()))
.Verifiable();
var formTagHelper = new FormTagHelper
{
@ -210,11 +214,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(
"form",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
generator
.Setup(mock => mock.GenerateForm(viewContext, "Index", "Home", null, "POST", null))
.Returns(new TagBuilder("form"))
.Returns(new TagBuilder("form", new HtmlEncoder()))
.Verifiable();
var formTagHelper = new FormTagHelper
{
@ -253,7 +258,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>
{
{ "aCTiON", htmlAction },
});
},
htmlEncoder: new HtmlEncoder());
var context = new TagHelperContext(
allAttributes: new Dictionary<string, object>()
@ -292,7 +298,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var generator = new Mock<IHtmlGenerator>();
generator.Setup(mock => mock.GenerateAntiForgery(It.IsAny<ViewContext>()))
.Returns(new TagBuilder("input"));
.Returns(new TagBuilder("input", new HtmlEncoder()));
var formTagHelper = new FormTagHelper
{
AntiForgery = antiForgery,
@ -304,7 +310,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>
{
{ "aCTiON", "my-action" },
});
},
htmlEncoder: new HtmlEncoder());
var context = new TagHelperContext(
allAttributes: new Dictionary<string, object>(),
items: new Dictionary<object, object>(),
@ -341,7 +348,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>
{
{ "action", "my-action" },
});
},
htmlEncoder: new HtmlEncoder());
if (propertyName == "asp-route-")
{
tagHelperOutput.Attributes.Add("asp-route-foo", "bar");

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -103,7 +104,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -159,7 +160,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(originalTagName, originalAttributes)
var output = new TagHelperOutput(originalTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = originalContent,
@ -169,7 +170,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
var tagHelper = GetTagHelper(htmlGenerator.Object, model: false, propertyName: nameof(Model.IsACar));
var tagBuilder = new TagBuilder("input")
var tagBuilder = new TagBuilder("input", new HtmlEncoder())
{
Attributes =
{
@ -190,7 +191,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
tagHelper.ViewContext,
tagHelper.For.ModelExplorer,
tagHelper.For.Name))
.Returns(new TagBuilder("hidden"))
.Returns(new TagBuilder("hidden", new HtmlEncoder()))
.Verifiable();
// Act
@ -250,7 +251,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -263,7 +264,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
tagHelper.For.Metadata.DataTypeName = dataTypeName;
tagHelper.InputTypeName = inputTypeName;
var tagBuilder = new TagBuilder("input")
var tagBuilder = new TagBuilder("input", new HtmlEncoder())
{
Attributes =
{
@ -338,7 +339,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -351,7 +352,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
tagHelper.For.Metadata.DataTypeName = dataTypeName;
tagHelper.InputTypeName = inputTypeName;
var tagBuilder = new TagBuilder("input")
var tagBuilder = new TagBuilder("input", new HtmlEncoder())
{
Attributes =
{
@ -423,7 +424,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -436,7 +437,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
tagHelper.InputTypeName = inputTypeName;
tagHelper.Value = value;
var tagBuilder = new TagBuilder("input")
var tagBuilder = new TagBuilder("input", new HtmlEncoder())
{
Attributes =
{
@ -523,7 +524,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -536,7 +537,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
tagHelper.For.Metadata.DataTypeName = dataTypeName;
tagHelper.InputTypeName = inputTypeName;
var tagBuilder = new TagBuilder("input")
var tagBuilder = new TagBuilder("input", new HtmlEncoder())
{
Attributes =
{
@ -588,7 +589,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, expectedAttributes)
var output = new TagHelperOutput(expectedTagName, expectedAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -644,7 +645,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, originalAttributes);
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder());
var tagHelper = new InputTagHelper
{
Format = "{0}",

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Xunit;
namespace Microsoft.AspNet.Mvc.TagHelpers
@ -194,7 +195,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, htmlAttributes)
var output = new TagHelperOutput(expectedTagName, htmlAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
PostContent = expectedPostContent,
@ -250,7 +251,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, expectedAttributes)
var output = new TagHelperOutput(expectedTagName, expectedAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,

View File

@ -15,6 +15,7 @@ using Microsoft.AspNet.Mvc.TagHelpers.Internal;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.Logging;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -100,6 +101,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var viewContext = MakeViewContext();
var helper = new LinkTagHelper
{
HtmlEncoder = new HtmlEncoder(),
Logger = logger.Object,
HostingEnvironment = hostingEnvironment,
ViewContext = viewContext,
@ -142,6 +144,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var viewContext = MakeViewContext();
var helper = new LinkTagHelper
{
HtmlEncoder = new HtmlEncoder(),
Logger = logger.Object,
HostingEnvironment = hostingEnvironment,
ViewContext = viewContext,
@ -306,6 +309,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
.Returns(new[] { "/css/site.css", "/base.css" });
var helper = new LinkTagHelper
{
HtmlEncoder = new HtmlEncoder(),
GlobbingUrlBuilder = globbingUrlBuilder.Object,
Logger = logger.Object,
HostingEnvironment = hostingEnvironment,
@ -321,6 +325,46 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
"<link href=\"/base.css\" rel=\"stylesheet\" />", output.Content);
}
[Fact]
public void RendersLinkTagsForGlobbedHrefResults_UsingProvidedEncoder()
{
// Arrange
var context = MakeTagHelperContext(
attributes: new Dictionary<string, object>
{
["href"] = "/css/site.css",
["rel"] = "stylesheet",
["asp-href-include"] = "**/*.css"
});
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, string>
{
["href"] = "/css/site.css",
["rel"] = "stylesheet"
});
var logger = new Mock<ILogger<LinkTagHelper>>();
var hostingEnvironment = MakeHostingEnvironment();
var viewContext = MakeViewContext();
var globbingUrlBuilder = new Mock<GlobbingUrlBuilder>();
globbingUrlBuilder.Setup(g => g.BuildUrlList("/css/site.css", "**/*.css", null))
.Returns(new[] { "/css/site.css", "/base.css" });
var helper = new LinkTagHelper
{
HtmlEncoder = new TestHtmlEncoder(),
GlobbingUrlBuilder = globbingUrlBuilder.Object,
Logger = logger.Object,
HostingEnvironment = hostingEnvironment,
ViewContext = viewContext,
HrefInclude = "**/*.css"
};
// Act
helper.Process(context, output);
// Assert
Assert.Equal("<link href=\"HtmlEncode[[/css/site.css]]\" rel=\"stylesheet\" />" +
"<link href=\"HtmlEncode[[/base.css]]\" rel=\"stylesheet\" />", output.Content);
}
private static ViewContext MakeViewContext()
{
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
@ -348,7 +392,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
attributes = attributes ?? new Dictionary<string, string>();
return new TagHelperOutput(tagName, attributes);
return new TagHelperOutput(tagName, attributes, new HtmlEncoder());
}
private static IHostingEnvironment MakeHostingEnvironment()
@ -364,5 +408,27 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
return hostingEnvironment.Object;
}
private class TestHtmlEncoder : IHtmlEncoder
{
public string HtmlEncode(string value)
{
return "HtmlEncode[[" + value + "]]";
}
public void HtmlEncode(string value, int startIndex, int charCount, TextWriter output)
{
output.Write("HtmlEncode[[");
output.Write(value.Substring(startIndex, charCount));
output.Write("]]");
}
public void HtmlEncode(char[] value, int startIndex, int charCount, TextWriter output)
{
output.Write("HtmlEncode[[");
output.Write(value, startIndex, charCount);
output.Write("]]");
}
}
}
}

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Xunit;
namespace Microsoft.AspNet.Mvc.TagHelpers
@ -141,7 +142,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult(originalContent));
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
Content = originalContent,
SelfClosing = false,
@ -200,7 +201,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult(originalContent));
var output = new TagHelperOutput(originalTagName, originalAttributes)
var output = new TagHelperOutput(originalTagName, originalAttributes, new HtmlEncoder())
{
PreContent = originalPreContent,
Content = originalContent,
@ -256,7 +257,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult(originalContent));
var output = new TagHelperOutput(originalTagName, originalAttributes)
var output = new TagHelperOutput(originalTagName, originalAttributes, new HtmlEncoder())
{
PreContent = originalPreContent,
Content = originalContent,

View File

@ -15,6 +15,7 @@ using Microsoft.AspNet.Mvc.TagHelpers.Internal;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.Logging;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -120,6 +121,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var viewContext = MakeViewContext();
var helper = new ScriptTagHelper
{
HtmlEncoder = new HtmlEncoder(),
Logger = logger,
HostingEnvironment = hostingEnvironment,
ViewContext = viewContext,
@ -346,6 +348,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var helper = new ScriptTagHelper
{
HtmlEncoder = new HtmlEncoder(),
Logger = logger,
ViewContext = viewContext,
HostingEnvironment = hostingEnvironment,
@ -387,7 +390,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Logger = logger.Object,
HostingEnvironment = hostingEnvironment,
ViewContext = viewContext,
SrcInclude = "**/*.js"
SrcInclude = "**/*.js",
HtmlEncoder = new HtmlEncoder()
};
// Act
@ -397,6 +401,44 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Assert.Equal("<script src=\"/js/site.js\"></script><script src=\"/common.js\"></script>", output.Content);
}
[Fact]
public async Task RendersScriptTagsForGlobbedSrcResults_UsesProvidedEncoder()
{
// Arrange
var context = MakeTagHelperContext(
attributes: new Dictionary<string, object>
{
["src"] = "/js/site.js",
["asp-src-include"] = "**/*.js"
});
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
{
["src"] = "/js/site.js"
});
var logger = new Mock<ILogger<ScriptTagHelper>>();
var hostingEnvironment = MakeHostingEnvironment();
var viewContext = MakeViewContext();
var globbingUrlBuilder = new Mock<GlobbingUrlBuilder>();
globbingUrlBuilder.Setup(g => g.BuildUrlList("/js/site.js", "**/*.js", null))
.Returns(new[] { "/js/site.js", "/common.js" });
var helper = new ScriptTagHelper
{
GlobbingUrlBuilder = globbingUrlBuilder.Object,
Logger = logger.Object,
HostingEnvironment = hostingEnvironment,
ViewContext = viewContext,
SrcInclude = "**/*.js",
HtmlEncoder = new TestHtmlEncoder()
};
// Act
await helper.ProcessAsync(context, output);
// Assert
Assert.Equal("<script src=\"HtmlEncode[[/js/site.js]]\"></script>" +
"<script src=\"HtmlEncode[[/common.js]]\"></script>", output.Content);
}
private TagHelperContext MakeTagHelperContext(
IDictionary<string, object> attributes = null,
string content = null)
@ -424,7 +466,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
attributes = attributes ?? new Dictionary<string, string>();
return new TagHelperOutput(tagName, attributes);
return new TagHelperOutput(tagName, attributes, new HtmlEncoder());
}
private TagHelperLogger<ScriptTagHelper> CreateLogger()
@ -445,5 +487,27 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
return hostingEnvironment.Object;
}
private class TestHtmlEncoder : IHtmlEncoder
{
public string HtmlEncode(string value)
{
return "HtmlEncode[[" + value + "]]";
}
public void HtmlEncode(string value, int startIndex, int charCount, TextWriter output)
{
output.Write("HtmlEncode[[");
output.Write(value.Substring(startIndex, charCount));
output.Write("]]");
}
public void HtmlEncode(char[] value, int startIndex, int charCount, TextWriter output)
{
output.Write("HtmlEncode[[");
output.Write(value, startIndex, charCount);
output.Write("]]");
}
}
}
}

View File

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -202,7 +203,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -287,7 +288,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -386,7 +387,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, originalAttributes)
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -470,7 +471,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, originalAttributes);
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder());
var metadataProvider = new EmptyModelMetadataProvider();
string model = null;
@ -536,7 +537,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(tagName, originalAttributes);
var output = new TagHelperOutput(tagName, originalAttributes, new HtmlEncoder());
var metadataProvider = new EmptyModelMetadataProvider();
var modelExplorer = metadataProvider.GetModelExplorerForType(modelType, model);
@ -592,7 +593,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, originalAttributes);
var output = new TagHelperOutput(expectedTagName, originalAttributes, new HtmlEncoder());
var tagHelper = new SelectTagHelper
{
Items = Enumerable.Empty<SelectListItem>(),

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Xunit;
namespace Microsoft.AspNet.Mvc.TagHelpers
@ -20,7 +21,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var tagHelperContext = new TagHelperContext(
allAttributes: new Dictionary<string, object>(StringComparer.Ordinal)
{
@ -49,7 +51,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>()
{
{ attributeName, "world2" }
});
},
htmlEncoder: new HtmlEncoder());
var expectedAttribute = new KeyValuePair<string, string>(attributeName, "world2");
var tagHelperContext = new TagHelperContext(
allAttributes: new Dictionary<string, object>(StringComparer.Ordinal)
@ -78,7 +81,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "route-Hello", "World" },
{ "Route-I", "Am" }
});
},
htmlEncoder: new HtmlEncoder());
var expectedAttribute = new KeyValuePair<string, string>("type", "btn");
tagHelperOutput.Attributes.Add(expectedAttribute);
var attributes = tagHelperOutput.FindPrefixedAttributes("route-");
@ -101,7 +105,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "routeHello", "World" },
{ "Routee-I", "Am" }
});
},
htmlEncoder: new HtmlEncoder());
// Act
var attributes = tagHelperOutput.FindPrefixedAttributes("route-");
@ -120,11 +125,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var expectedAttribute = new KeyValuePair<string, string>("type", "btn");
tagHelperOutput.Attributes.Add(expectedAttribute);
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
tagBuilder.Attributes.Add("type", "hello");
// Act
@ -141,10 +147,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
tagHelperOutput.Attributes.Add("class", "Hello");
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
tagBuilder.Attributes.Add("class", "btn");
var expectedAttribute = new KeyValuePair<string, string>("class", "Hello btn");
@ -167,10 +174,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
tagHelperOutput.Attributes.Add(originalName, "Hello");
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
tagBuilder.Attributes.Add(updateName, "btn");
// Act
@ -187,9 +195,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
var expectedAttribute = new KeyValuePair<string, string>("visible", "val < 3");
tagBuilder.Attributes.Add(expectedAttribute);
@ -207,9 +216,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
var expectedAttribute1 = new KeyValuePair<string, string>("class", "btn");
var expectedAttribute2 = new KeyValuePair<string, string>("class2", "btn");
tagBuilder.Attributes.Add(expectedAttribute1);
@ -232,11 +242,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var expectedAttribute = new KeyValuePair<string, string>("class", "btn");
tagHelperOutput.Attributes.Add(expectedAttribute);
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
// Act
tagHelperOutput.MergeAttributes(tagBuilder);
@ -252,11 +263,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Arrange
var tagHelperOutput = new TagHelperOutput(
"p",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var expectedOutputAttribute = new KeyValuePair<string, string>("class", "btn");
tagHelperOutput.Attributes.Add(expectedOutputAttribute);
var tagBuilder = new TagBuilder("p");
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
var expectedBuilderAttribute = new KeyValuePair<string, string>("for", "hello");
tagBuilder.Attributes.Add(expectedBuilderAttribute);

View File

@ -11,6 +11,7 @@ using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;
using Moq;
namespace Microsoft.AspNet.Mvc.TagHelpers
@ -38,7 +39,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
IScopedInstance<ActionBindingContext> bindingContextAccessor,
IUrlHelper urlHelper,
IDictionary<string, object> validationAttributes)
: base(GetAntiForgery(), bindingContextAccessor, metadataProvider, urlHelper)
: base(GetAntiForgery(), bindingContextAccessor, metadataProvider, urlHelper, new HtmlEncoder())
{
_validationAttributes = validationAttributes;
}
@ -65,7 +66,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
public override TagBuilder GenerateAntiForgery(ViewContext viewContext)
{
return new TagBuilder("input")
return new TagBuilder("input", new HtmlEncoder())
{
Attributes =
{
@ -95,7 +96,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Mock.Of<IClaimUidExtractor>(),
Mock.Of<IDataProtectionProvider>(),
Mock.Of<IAntiForgeryAdditionalDataProvider>(),
optionsAccessor.Object);
optionsAccessor.Object,
new HtmlEncoder());
return antiForgery;
}

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.WebEncoders;
using Xunit;
namespace Microsoft.AspNet.Mvc.TagHelpers
@ -121,7 +122,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
{ "class", "form-control" },
};
var output = new TagHelperOutput(expectedTagName, htmlAttributes)
var output = new TagHelperOutput(expectedTagName, htmlAttributes, new HtmlEncoder())
{
Content = "original content",
SelfClosing = true,
@ -174,7 +175,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(expectedTagName, expectedAttributes)
var output = new TagHelperOutput(expectedTagName, expectedAttributes, new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -46,7 +47,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>
{
{ "id", "myvalidationmessage" }
})
},
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -96,7 +98,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
getChildContentAsync: () => Task.FromResult("Something"));
var output = new TagHelperOutput(
"span",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -107,7 +110,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
generator
.Setup(mock =>
mock.GenerateValidationMessage(expectedViewContext, "Hello", null, null, null))
.Returns(new TagBuilder("span"))
.Returns(new TagBuilder("span", new HtmlEncoder()))
.Verifiable();
validationMessageTagHelper.Generator = generator.Object;
validationMessageTagHelper.ViewContext = expectedViewContext;
@ -137,7 +140,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(
"span",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
Content = outputContent
};
@ -147,7 +151,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult(childContent));
var tagBuilder = new TagBuilder("span2")
var tagBuilder = new TagBuilder("span2", new HtmlEncoder())
{
InnerHtml = "New HTML"
};
@ -193,14 +197,15 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var output = new TagHelperOutput(
"span",
attributes: new Dictionary<string, string>());
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder());
var context = new TagHelperContext(
allAttributes: new Dictionary<string, object>(),
items: new Dictionary<object, object>(),
uniqueId: "test",
getChildContentAsync: () => Task.FromResult(childContent));
var tagBuilder = new TagBuilder("span2")
var tagBuilder = new TagBuilder("span2", new HtmlEncoder())
{
InnerHtml = "New HTML"
};
@ -243,7 +248,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var expectedPostContent = "original post-content";
var output = new TagHelperOutput(
"span",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,

View File

@ -11,6 +11,7 @@ using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Testing;
using Microsoft.Framework.WebEncoders;
using Moq;
using Xunit;
@ -52,7 +53,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
attributes: new Dictionary<string, string>
{
{ "class", "form-control" }
})
},
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -98,7 +100,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var expectedPostContent = "original post-content";
var output = new TagHelperOutput(
"div",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -113,7 +116,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
null, // message
null, // headerTag
null)) // htmlAttributes
.Returns(new TagBuilder("div"))
.Returns(new TagBuilder("div", new HtmlEncoder()))
.Verifiable();
validationSummaryTagHelper.ViewContext = expectedViewContext;
validationSummaryTagHelper.Generator = generator.Object;
@ -141,13 +144,14 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var expectedContent = "original content";
var output = new TagHelperOutput(
"div",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
PostContent = "Content of validation summary"
};
var tagBuilder = new TagBuilder("span2")
var tagBuilder = new TagBuilder("span2", new HtmlEncoder())
{
InnerHtml = "New HTML"
};
@ -199,7 +203,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var expectedPostContent = "original post-content";
var output = new TagHelperOutput(
"div",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
@ -236,13 +241,14 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var expectedContent = "original content";
var output = new TagHelperOutput(
"div",
attributes: new Dictionary<string, string>())
attributes: new Dictionary<string, string>(),
htmlEncoder: new HtmlEncoder())
{
PreContent = expectedPreContent,
Content = expectedContent,
PostContent = "Content of validation message",
};
var tagBuilder = new TagBuilder("span2")
var tagBuilder = new TagBuilder("span2", new HtmlEncoder())
{
InnerHtml = "New HTML"
};

View File

@ -19,7 +19,7 @@ namespace ActivatorWebSite.TagHelpers
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var builder = new TagBuilder("h2");
var builder = new TagBuilder("h2", HtmlHelper.HtmlEncoder);
var title = ViewContext.ViewBag.Title;
builder.InnerHtml = HtmlHelper.Encode(title);
output.PreContent = builder.ToString();

View File

@ -14,16 +14,11 @@ namespace TagHelpersWebSite.TagHelpers
private static readonly Dictionary<string, string> PrettyTagStyles =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "a", @"background-color: gray;
color: white;
border-radius: 3px;
border: 1px solid black;
padding: 3px;
font-family: cursive;" },
{ "strong", @"font-size: 1.25em;
text-decoration: underline;" },
{ "h1", @"font-family: cursive;" },
{ "h3", @"font-family: cursive;" }
{ "a", "background-color: gray;color: white;border-radius: 3px;"
+ "border: 1px solid black;padding: 3px;font-family: cursive;" },
{ "strong", "font-size: 1.25em;text-decoration: underline;" },
{ "h1", "font-family: cursive;" },
{ "h3", "font-family: cursive;" }
};
public bool? MakePretty { get; set; }