From bb792e9e10050b9520865d2e086864e7f72dc174 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Fri, 2 Mar 2018 13:13:07 -0800 Subject: [PATCH 1/2] Do not use `FormattedModelValue` in password editor template - #7418 - add quirk switch to reverse this if necessary --- .../Internal/DefaultEditorTemplates.cs | 9 +- .../Internal/DefaultEditorTemplatesTest.cs | 107 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/DefaultEditorTemplates.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/DefaultEditorTemplates.cs index 09c2c60e97..408448c651 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/DefaultEditorTemplates.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/DefaultEditorTemplates.cs @@ -20,6 +20,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal public static class DefaultEditorTemplates { private const string HtmlAttributeKey = "htmlAttributes"; + private const string UsePasswordValue = "Switch.Microsoft.AspNetCore.Mvc.UsePasswordValue"; public static IHtmlContent BooleanTemplate(IHtmlHelper htmlHelper) { @@ -312,9 +313,15 @@ public static IHtmlContent ObjectTemplate(IHtmlHelper htmlHelper) public static IHtmlContent PasswordTemplate(IHtmlHelper htmlHelper) { + object value = null; + if (AppContext.TryGetSwitch(UsePasswordValue, out var usePasswordValue) && usePasswordValue) + { + value = htmlHelper.ViewData.TemplateInfo.FormattedModelValue; + } + return htmlHelper.Password( expression: null, - value: htmlHelper.ViewData.TemplateInfo.FormattedModelValue, + value: value, htmlAttributes: CreateHtmlAttributes(htmlHelper, "text-box single-line password")); } diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs index e7e1b568bc..db1d2e5527 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs @@ -521,6 +521,113 @@ public void MultilineTextTemplate_ReturnsTextArea() Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); } + [Fact] + public void PasswordTemplate_ReturnsInputElement_IgnoresExpressionValue() + { + // Arrange + var expected = ""; + + var model = "Model string"; + + var helper = DefaultTemplatesUtilities.GetHtmlHelper(model); + var viewData = helper.ViewData; + var templateInfo = viewData.TemplateInfo; + templateInfo.HtmlFieldPrefix = "FieldPrefix"; + + // Act + var result = DefaultEditorTemplates.PasswordTemplate(helper); + + // Assert + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); + } + + [Fact] + public void PasswordTemplate_ReturnsInputElement_IgnoresFormattedModelValue() + { + // Arrange + var expected = ""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); + var viewData = helper.ViewData; + var templateInfo = viewData.TemplateInfo; + templateInfo.HtmlFieldPrefix = "FieldPrefix"; + + templateInfo.FormattedModelValue = "Formatted string"; + + // Act + var result = DefaultEditorTemplates.PasswordTemplate(helper); + + // Assert + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); + } + + [Fact] + public void PasswordTemplate_ReturnsInputElement_IgnoresModelState() + { + // Arrange + var expected = ""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); + var viewData = helper.ViewData; + var templateInfo = viewData.TemplateInfo; + templateInfo.HtmlFieldPrefix = "FieldPrefix"; + + var modelState = viewData.ModelState; + modelState.SetModelValue("FieldPRefix", "Raw model string", "Attempted model string"); + + // Act + var result = DefaultEditorTemplates.PasswordTemplate(helper); + + // Assert + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); + } + + [Fact] + public void PasswordTemplate_ReturnsInputElement_IgnoresViewData() + { + // Arrange + var expected = ""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); + var viewData = helper.ViewData; + var templateInfo = viewData.TemplateInfo; + templateInfo.HtmlFieldPrefix = "FieldPrefix"; + + viewData["FieldPrefix"] = "ViewData string"; + + // Act + var result = DefaultEditorTemplates.PasswordTemplate(helper); + + // Assert + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); + } + + [Fact] + public void PasswordTemplate_ReturnsInputElement_UsesHtmlAttributes() + { + // Arrange + var expected = ""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); + var viewData = helper.ViewData; + var templateInfo = viewData.TemplateInfo; + templateInfo.HtmlFieldPrefix = "FieldPrefix"; + + viewData["htmlAttributes"] = new { @class = "super", value = "Html attributes string" }; + + // Act + var result = DefaultEditorTemplates.PasswordTemplate(helper); + + // Assert + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); + } + [Theory] [MemberData(nameof(TemplateNameData))] public void Editor_CallsExpectedHtmlHelper(string templateName, string expectedResult) From 848266fdd6cbcb9b3a51b947a4c34d4d66f28247 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Fri, 2 Mar 2018 15:59:21 -0800 Subject: [PATCH 2/2] Consolidate tests --- .../Internal/DefaultEditorTemplatesTest.cs | 66 ++----------------- 1 file changed, 4 insertions(+), 62 deletions(-) diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs index db1d2e5527..793f7a176e 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs @@ -522,13 +522,14 @@ public void MultilineTextTemplate_ReturnsTextArea() } [Fact] - public void PasswordTemplate_ReturnsInputElement_IgnoresExpressionValue() + public void PasswordTemplate_ReturnsInputElement_IgnoresValues() { // Arrange var expected = ""; + // Template ignores Model. var model = "Model string"; var helper = DefaultTemplatesUtilities.GetHtmlHelper(model); @@ -536,68 +537,9 @@ public void PasswordTemplate_ReturnsInputElement_IgnoresExpressionValue() var templateInfo = viewData.TemplateInfo; templateInfo.HtmlFieldPrefix = "FieldPrefix"; - // Act - var result = DefaultEditorTemplates.PasswordTemplate(helper); - - // Assert - Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); - } - - [Fact] - public void PasswordTemplate_ReturnsInputElement_IgnoresFormattedModelValue() - { - // Arrange - var expected = ""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); - var viewData = helper.ViewData; - var templateInfo = viewData.TemplateInfo; - templateInfo.HtmlFieldPrefix = "FieldPrefix"; - + // Template ignores FormattedModelValue, ModelState and ViewData. templateInfo.FormattedModelValue = "Formatted string"; - - // Act - var result = DefaultEditorTemplates.PasswordTemplate(helper); - - // Assert - Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); - } - - [Fact] - public void PasswordTemplate_ReturnsInputElement_IgnoresModelState() - { - // Arrange - var expected = ""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); - var viewData = helper.ViewData; - var templateInfo = viewData.TemplateInfo; - templateInfo.HtmlFieldPrefix = "FieldPrefix"; - - var modelState = viewData.ModelState; - modelState.SetModelValue("FieldPRefix", "Raw model string", "Attempted model string"); - - // Act - var result = DefaultEditorTemplates.PasswordTemplate(helper); - - // Assert - Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(result)); - } - - [Fact] - public void PasswordTemplate_ReturnsInputElement_IgnoresViewData() - { - // Arrange - var expected = ""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); - var viewData = helper.ViewData; - var templateInfo = viewData.TemplateInfo; - templateInfo.HtmlFieldPrefix = "FieldPrefix"; - + viewData.ModelState.SetModelValue("FieldPrefix", "Raw model string", "Attempted model string"); viewData["FieldPrefix"] = "ViewData string"; // Act