Do not generate a validation summary when `excludePropertyErrors` unless specific model has an error
- #5209 - update affected `HtmlHelperValiationSummaryTest` and functional tests - add `ValidationSummaryTagHelperTest` tests to cover related scenarios ##### Behaviour changes when no errors exist for the model: ###### Tag helper ``` html <div asp-validation-summary="ModelOnly" class="order"><h3>Oopsie<h3></div> ``` previously generated ``` html <div class="order validation-summary-errors"><h3>Oopsie</h3><ul><li style="display:none"></li> </ul></div> ``` and now generates ``` html <div class="order"><h3>Oopsie</h3></div> ``` ###### HTML helper ``` c# @Html.ValidationSummary(excludePropertyErrors: true, message: "Oopsie") ``` previously generated ``` html <div class=\"validation-summary-errors\"><span>Oopsie</span> <ul><li style=\"display:none\"></li> </ul></div> ``` and now generates nothing (`@HtmlString.Empty`).
This commit is contained in:
parent
43a0a5a9f1
commit
eee1a9fef4
|
|
@ -816,9 +816,19 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
throw new ArgumentNullException(nameof(viewContext));
|
throw new ArgumentNullException(nameof(viewContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewContext.ViewData.ModelState.IsValid && (!viewContext.ClientValidationEnabled || excludePropertyErrors))
|
var viewData = viewContext.ViewData;
|
||||||
|
if (!viewContext.ClientValidationEnabled && viewData.ModelState.IsValid)
|
||||||
{
|
{
|
||||||
// No client side validation/updates
|
// Client-side validation is not enabled to add to the generated element and element will be empty.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelStateEntry entryForModel;
|
||||||
|
if (excludePropertyErrors &&
|
||||||
|
(!viewData.ModelState.TryGetValue(viewData.TemplateInfo.HtmlFieldPrefix, out entryForModel) ||
|
||||||
|
entryForModel.Errors.Count == 0))
|
||||||
|
{
|
||||||
|
// Client-side validation (if enabled) will not affect the generated element and element will be empty.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -829,6 +839,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
{
|
{
|
||||||
headerTag = viewContext.ValidationSummaryMessageElement;
|
headerTag = viewContext.ValidationSummaryMessageElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
var messageTag = new TagBuilder(headerTag);
|
var messageTag = new TagBuilder(headerTag);
|
||||||
messageTag.InnerHtml.SetContent(message);
|
messageTag.InnerHtml.SetContent(message);
|
||||||
wrappedMessage.AppendLine(messageTag);
|
wrappedMessage.AppendLine(messageTag);
|
||||||
|
|
@ -841,7 +852,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
// If excludePropertyErrors is true, describe any validation issue with the current model in a single item.
|
// If excludePropertyErrors is true, describe any validation issue with the current model in a single item.
|
||||||
// Otherwise, list individual property errors.
|
// Otherwise, list individual property errors.
|
||||||
var isHtmlSummaryModified = false;
|
var isHtmlSummaryModified = false;
|
||||||
var modelStates = ValidationHelpers.GetModelStateList(viewContext.ViewData, excludePropertyErrors);
|
var modelStates = ValidationHelpers.GetModelStateList(viewData, excludePropertyErrors);
|
||||||
|
|
||||||
var htmlSummary = new TagBuilder("ul");
|
var htmlSummary = new TagBuilder("ul");
|
||||||
foreach (var modelState in modelStates)
|
foreach (var modelState in modelStates)
|
||||||
|
|
@ -871,7 +882,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
var tagBuilder = new TagBuilder("div");
|
var tagBuilder = new TagBuilder("div");
|
||||||
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
|
tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
|
||||||
|
|
||||||
if (viewContext.ViewData.ModelState.IsValid)
|
if (viewData.ModelState.IsValid)
|
||||||
{
|
{
|
||||||
tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryValidCssClassName);
|
tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryValidCssClassName);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected =
|
var expected =
|
||||||
@"<div class=""validation-summary-errors""><validationSummaryElement>MySummary</validationSummaryElement>
|
@"<div class=""validation-summary-errors""><validationSummaryElement>MySummary</validationSummaryElement>
|
||||||
<ul><li style=""display:none""></li>
|
<ul><li>A model error occurred.</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<validationMessageElement class=""field-validation-error"">An error occurred.</validationMessageElement>
|
<validationMessageElement class=""field-validation-error"">An error occurred.</validationMessageElement>
|
||||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime"" value=""2000-01-02T03:04:05.060+00:00"" /> </div>
|
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime"" value=""2000-01-02T03:04:05.060+00:00"" /> </div>
|
||||||
|
|
||||||
<div class=""validation-summary-errors""><validationSummaryElement>MySummary</validationSummaryElement>
|
<div class=""validation-summary-errors""><validationSummaryElement>MySummary</validationSummaryElement>
|
||||||
<ul><li style=""display:none""></li>
|
<ul><li>A model error occurred.</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<validationMessageElement class=""field-validation-error"">An error occurred.</validationMessageElement>
|
<validationMessageElement class=""field-validation-error"">An error occurred.</validationMessageElement>
|
||||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||||
|
|
@ -54,7 +54,7 @@ False";
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected =
|
var expected =
|
||||||
@"<div class=""validation-summary-errors""><ValidationSummaryInView>MySummary</ValidationSummaryInView>
|
@"<div class=""validation-summary-errors""><ValidationSummaryInView>MySummary</ValidationSummaryInView>
|
||||||
<ul><li style=""display:none""></li>
|
<ul><li>A model error occurred.</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<ValidationInView class=""field-validation-error"" data-valmsg-for=""Error"" data-valmsg-replace=""true"">An error occurred.</ValidationInView>
|
<ValidationInView class=""field-validation-error"" data-valmsg-for=""Error"" data-valmsg-replace=""true"">An error occurred.</ValidationInView>
|
||||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||||
|
|
@ -63,7 +63,7 @@ False";
|
||||||
|
|
||||||
True
|
True
|
||||||
<div class=""validation-summary-errors""><ValidationSummaryInPartialView>MySummary</ValidationSummaryInPartialView>
|
<div class=""validation-summary-errors""><ValidationSummaryInPartialView>MySummary</ValidationSummaryInPartialView>
|
||||||
<ul><li style=""display:none""></li>
|
<ul><li>A model error occurred.</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<ValidationInPartialView class=""field-validation-error"" data-valmsg-for=""Error"" data-valmsg-replace=""true"">An error occurred.</ValidationInPartialView>
|
<ValidationInPartialView class=""field-validation-error"" data-valmsg-for=""Error"" data-valmsg-replace=""true"">An error occurred.</ValidationInPartialView>
|
||||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,7 @@
|
||||||
<div class="order validation-summary-errors" data-valmsg-summary="true"><ul><li>The value '' is invalid.</li>
|
<div class="order validation-summary-errors" data-valmsg-summary="true"><ul><li>The value '' is invalid.</li>
|
||||||
<li>The Password field is required.</li>
|
<li>The Password field is required.</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<div class="order validation-summary-errors"><ul><li style="display:none"></li>
|
<div class="order"></div>
|
||||||
</ul></div>
|
|
||||||
<input type="submit"/>
|
<input type="submit"/>
|
||||||
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
|
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Html;
|
using Microsoft.AspNetCore.Html;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
@ -42,8 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ProcessAsync_GeneratesExpectedOutput_WithNoErrorsData))]
|
[MemberData(nameof(ProcessAsync_GeneratesExpectedOutput_WithNoErrorsData))]
|
||||||
public async Task ProcessAsync_GeneratesExpectedOutput_WithNoErrors(
|
public async Task ProcessAsync_GeneratesExpectedOutput_WithNoErrors(ModelStateDictionary modelState)
|
||||||
ModelStateDictionary modelState)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expectedTagName = "not-div";
|
var expectedTagName = "not-div";
|
||||||
|
|
@ -53,8 +51,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
var expectedPreContent = "original pre-content";
|
var expectedPreContent = "original pre-content";
|
||||||
var expectedContent = "original content";
|
var expectedContent = "original content";
|
||||||
var tagHelperContext = new TagHelperContext(
|
var tagHelperContext = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
var output = new TagHelperOutput(
|
var output = new TagHelperOutput(
|
||||||
|
|
@ -65,9 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
},
|
},
|
||||||
getChildContentAsync: (useCachedResult, encoder) =>
|
getChildContentAsync: (useCachedResult, encoder) =>
|
||||||
{
|
{
|
||||||
var tagHelperContent = new DefaultTagHelperContent();
|
throw new InvalidOperationException("getChildContentAsync called unexpectedly");
|
||||||
tagHelperContent.SetContent("Something");
|
|
||||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
|
||||||
});
|
});
|
||||||
output.PreContent.SetContent(expectedPreContent);
|
output.PreContent.SetContent(expectedPreContent);
|
||||||
output.Content.SetContent(expectedContent);
|
output.Content.SetContent(expectedContent);
|
||||||
|
|
@ -85,11 +80,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);
|
await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(2, output.Attributes.Count);
|
Assert.Collection(
|
||||||
var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class"));
|
output.Attributes,
|
||||||
Assert.Equal("form-control validation-summary-valid", attribute.Value);
|
attribute =>
|
||||||
attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-summary"));
|
{
|
||||||
Assert.Equal("true", attribute.Value);
|
Assert.Equal("class", attribute.Name);
|
||||||
|
Assert.Equal("form-control validation-summary-valid", attribute.Value);
|
||||||
|
},
|
||||||
|
attribute =>
|
||||||
|
{
|
||||||
|
Assert.Equal("data-valmsg-summary", attribute.Name);
|
||||||
|
Assert.Equal("true", attribute.Value);
|
||||||
|
});
|
||||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
|
|
@ -98,6 +100,120 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
Assert.Equal(expectedTagName, output.TagName);
|
Assert.Equal(expectedTagName, output.TagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(ProcessAsync_GeneratesExpectedOutput_WithNoErrorsData))]
|
||||||
|
public async Task ProcessAsync_DoesNothingIfClientSideValiationDisabled_WithNoErrorsData(
|
||||||
|
ModelStateDictionary modelStateDictionary)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataProvider = new TestModelMetadataProvider();
|
||||||
|
var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
|
||||||
|
var viewContext = CreateViewContext();
|
||||||
|
viewContext.ClientValidationEnabled = false;
|
||||||
|
|
||||||
|
var validationSummaryTagHelper = new ValidationSummaryTagHelper(htmlGenerator)
|
||||||
|
{
|
||||||
|
ValidationSummary = ValidationSummary.All,
|
||||||
|
ViewContext = viewContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
var output = new TagHelperOutput(
|
||||||
|
"div",
|
||||||
|
new TagHelperAttributeList(),
|
||||||
|
(useCachedResult, encoder) =>
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("getChildContentAsync called unexpectedly.");
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = new TagHelperContext(
|
||||||
|
new TagHelperAttributeList(),
|
||||||
|
items: new Dictionary<object, object>(),
|
||||||
|
uniqueId: "test");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await validationSummaryTagHelper.ProcessAsync(context, output);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("div", output.TagName);
|
||||||
|
Assert.Empty(output.Attributes);
|
||||||
|
Assert.False(output.IsContentModified);
|
||||||
|
Assert.False(output.PreContent.IsModified);
|
||||||
|
Assert.False(output.PreElement.IsModified);
|
||||||
|
Assert.False(output.PostContent.IsModified);
|
||||||
|
Assert.False(output.PostElement.IsModified);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<string, ModelStateDictionary> ProcessAsync_DoesNothingIfModelOnly_WithNoModelErrorData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var emptyModelState = new ModelStateDictionary();
|
||||||
|
|
||||||
|
var modelState = new ModelStateDictionary();
|
||||||
|
SetValidModelState(modelState);
|
||||||
|
|
||||||
|
var invalidModelState = new ModelStateDictionary();
|
||||||
|
SetValidModelState(invalidModelState);
|
||||||
|
invalidModelState.AddModelError($"{nameof(Model.Strings)}[1]", "This value is invalid.");
|
||||||
|
|
||||||
|
return new TheoryData<string, ModelStateDictionary>
|
||||||
|
{
|
||||||
|
{ string.Empty, emptyModelState },
|
||||||
|
{ string.Empty, modelState },
|
||||||
|
{ nameof(Model.Text), modelState },
|
||||||
|
{ "not-a-key", modelState },
|
||||||
|
{ string.Empty, invalidModelState },
|
||||||
|
{ $"{nameof(Model.Strings)}[2]", invalidModelState },
|
||||||
|
{ nameof(Model.Text), invalidModelState },
|
||||||
|
{ "not-a-key", invalidModelState },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(ProcessAsync_DoesNothingIfModelOnly_WithNoModelErrorData))]
|
||||||
|
public async Task ProcessAsync_DoesNothingIfModelOnly_WithNoModelError(
|
||||||
|
string prefix,
|
||||||
|
ModelStateDictionary modelStateDictionary)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataProvider = new TestModelMetadataProvider();
|
||||||
|
var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
|
||||||
|
var viewContext = CreateViewContext();
|
||||||
|
viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
|
||||||
|
|
||||||
|
var validationSummaryTagHelper = new ValidationSummaryTagHelper(htmlGenerator)
|
||||||
|
{
|
||||||
|
ValidationSummary = ValidationSummary.ModelOnly,
|
||||||
|
ViewContext = viewContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
var output = new TagHelperOutput(
|
||||||
|
"div",
|
||||||
|
new TagHelperAttributeList(),
|
||||||
|
(useCachedResult, encoder) =>
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("getChildContentAsync called unexpectedly.");
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = new TagHelperContext(
|
||||||
|
new TagHelperAttributeList(),
|
||||||
|
items: new Dictionary<object, object>(),
|
||||||
|
uniqueId: "test");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await validationSummaryTagHelper.ProcessAsync(context, output);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("div", output.TagName);
|
||||||
|
Assert.Empty(output.Attributes);
|
||||||
|
Assert.False(output.IsContentModified);
|
||||||
|
Assert.False(output.PreContent.IsModified);
|
||||||
|
Assert.False(output.PreElement.IsModified);
|
||||||
|
Assert.False(output.PostContent.IsModified);
|
||||||
|
Assert.False(output.PostElement.IsModified);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(ValidationSummary.All)]
|
[InlineData(ValidationSummary.All)]
|
||||||
[InlineData(ValidationSummary.ModelOnly)]
|
[InlineData(ValidationSummary.ModelOnly)]
|
||||||
|
|
@ -117,8 +233,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
var expectedPreContent = "original pre-content";
|
var expectedPreContent = "original pre-content";
|
||||||
var expectedContent = "original content";
|
var expectedContent = "original content";
|
||||||
var tagHelperContext = new TagHelperContext(
|
var tagHelperContext = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
var output = new TagHelperOutput(
|
var output = new TagHelperOutput(
|
||||||
|
|
@ -178,8 +293,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
var expectedPreContent = "original pre-content";
|
var expectedPreContent = "original pre-content";
|
||||||
var expectedContent = "original content";
|
var expectedContent = "original content";
|
||||||
var tagHelperContext = new TagHelperContext(
|
var tagHelperContext = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
var output = new TagHelperOutput(
|
var output = new TagHelperOutput(
|
||||||
|
|
@ -211,11 +325,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);
|
await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(2, output.Attributes.Count);
|
Assert.Collection(
|
||||||
var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class"));
|
output.Attributes,
|
||||||
Assert.Equal("form-control validation-summary-errors", attribute.Value);
|
attribute =>
|
||||||
attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-summary"));
|
{
|
||||||
Assert.Equal("true", attribute.Value);
|
Assert.Equal("class", attribute.Name);
|
||||||
|
Assert.Equal("form-control validation-summary-errors", attribute.Value);
|
||||||
|
},
|
||||||
|
attribute =>
|
||||||
|
{
|
||||||
|
Assert.Equal("data-valmsg-summary", attribute.Name);
|
||||||
|
Assert.Equal("true", attribute.Value);
|
||||||
|
});
|
||||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
|
|
@ -266,8 +387,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
validationSummaryTagHelper.ViewContext = expectedViewContext;
|
validationSummaryTagHelper.ViewContext = expectedViewContext;
|
||||||
|
|
||||||
var context = new TagHelperContext(
|
var context = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
|
|
||||||
|
|
@ -288,9 +408,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
// Arrange
|
// Arrange
|
||||||
var tagBuilder = new TagBuilder("span2");
|
var tagBuilder = new TagBuilder("span2");
|
||||||
tagBuilder.InnerHtml.SetHtmlContent("New HTML");
|
tagBuilder.InnerHtml.SetHtmlContent("New HTML");
|
||||||
|
tagBuilder.Attributes.Add("anything", "something");
|
||||||
tagBuilder.Attributes.Add("data-foo", "bar");
|
tagBuilder.Attributes.Add("data-foo", "bar");
|
||||||
tagBuilder.Attributes.Add("data-hello", "world");
|
tagBuilder.Attributes.Add("data-hello", "world");
|
||||||
tagBuilder.Attributes.Add("anything", "something");
|
|
||||||
|
|
||||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||||
generator
|
generator
|
||||||
|
|
@ -322,8 +442,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
validationSummaryTagHelper.ViewContext = viewContext;
|
validationSummaryTagHelper.ViewContext = viewContext;
|
||||||
|
|
||||||
var context = new TagHelperContext(
|
var context = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
|
|
||||||
|
|
@ -332,13 +451,23 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("div", output.TagName);
|
Assert.Equal("div", output.TagName);
|
||||||
Assert.Equal(3, output.Attributes.Count);
|
Assert.Collection(
|
||||||
var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-foo"));
|
output.Attributes,
|
||||||
Assert.Equal("bar", attribute.Value);
|
attribute =>
|
||||||
attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-hello"));
|
{
|
||||||
Assert.Equal("world", attribute.Value);
|
Assert.Equal("anything", attribute.Name);
|
||||||
attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("anything"));
|
Assert.Equal("something", attribute.Value);
|
||||||
Assert.Equal("something", attribute.Value);
|
},
|
||||||
|
attribute =>
|
||||||
|
{
|
||||||
|
Assert.Equal("data-foo", attribute.Name);
|
||||||
|
Assert.Equal("bar", attribute.Value);
|
||||||
|
},
|
||||||
|
attribute =>
|
||||||
|
{
|
||||||
|
Assert.Equal("data-hello", attribute.Name);
|
||||||
|
Assert.Equal("world", attribute.Value);
|
||||||
|
});
|
||||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||||
Assert.Equal("Content of validation summaryNew HTML", output.PostContent.GetContent());
|
Assert.Equal("Content of validation summaryNew HTML", output.PostContent.GetContent());
|
||||||
|
|
@ -371,8 +500,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
validationSummaryTagHelper.ViewContext = viewContext;
|
validationSummaryTagHelper.ViewContext = viewContext;
|
||||||
|
|
||||||
var context = new TagHelperContext(
|
var context = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
|
|
||||||
|
|
@ -427,8 +555,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
validationSummaryTagHelper.ViewContext = viewContext;
|
validationSummaryTagHelper.ViewContext = viewContext;
|
||||||
|
|
||||||
var context = new TagHelperContext(
|
var context = new TagHelperContext(
|
||||||
allAttributes: new TagHelperAttributeList(
|
allAttributes: new TagHelperAttributeList(),
|
||||||
Enumerable.Empty<TagHelperAttribute>()),
|
|
||||||
items: new Dictionary<object, object>(),
|
items: new Dictionary<object, object>(),
|
||||||
uniqueId: "test");
|
uniqueId: "test");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,6 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var basicDiv = "<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul>" +
|
|
||||||
"<li style=\"display:none\"></li>" + Environment.NewLine +
|
|
||||||
"</ul></div>";
|
|
||||||
var divWithError = "<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul>" +
|
var divWithError = "<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul>" +
|
||||||
"<li>HtmlEncode[[This is my validation message]]</li>" + Environment.NewLine +
|
"<li>HtmlEncode[[This is my validation message]]</li>" + Environment.NewLine +
|
||||||
"</ul></div>";
|
"</ul></div>";
|
||||||
|
|
@ -89,8 +86,8 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{
|
{
|
||||||
{ false, false, divWithError, divWithError },
|
{ false, false, divWithError, divWithError },
|
||||||
{ false, true, divWithErrorAndSummary, divWithErrorAndSummary },
|
{ false, true, divWithErrorAndSummary, divWithErrorAndSummary },
|
||||||
{ true, false, divWithError, basicDiv },
|
{ true, false, divWithError, string.Empty },
|
||||||
{ true, true, divWithError, basicDiv },
|
{ true, true, divWithError, string.Empty },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -100,9 +97,6 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var basicDiv = "<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul>" +
|
|
||||||
"<li style=\"display:none\"></li>" + Environment.NewLine +
|
|
||||||
"</ul></div>";
|
|
||||||
var divWithRootError = "<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul>" +
|
var divWithRootError = "<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul>" +
|
||||||
"<li>HtmlEncode[[This is an error for the model root.]]</li>" + Environment.NewLine +
|
"<li>HtmlEncode[[This is an error for the model root.]]</li>" + Environment.NewLine +
|
||||||
"<li>HtmlEncode[[This is another error for the model root.]]</li>" + Environment.NewLine +
|
"<li>HtmlEncode[[This is another error for the model root.]]</li>" + Environment.NewLine +
|
||||||
|
|
@ -129,7 +123,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{ false, "some.unrelated.prefix", divWithAllErrors },
|
{ false, "some.unrelated.prefix", divWithAllErrors },
|
||||||
{ true, string.Empty, divWithRootError },
|
{ true, string.Empty, divWithRootError },
|
||||||
{ true, "Property3", divWithProperty3Error },
|
{ true, "Property3", divWithProperty3Error },
|
||||||
{ true, "some.unrelated.prefix", basicDiv },
|
{ true, "some.unrelated.prefix", string.Empty },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -526,11 +520,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
var validationSummaryResult = helper.ValidationSummary(excludePropertyErrors: true);
|
var validationSummaryResult = helper.ValidationSummary(excludePropertyErrors: true);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(
|
Assert.Equal(HtmlString.Empty, validationSummaryResult);
|
||||||
"<div class=\"HtmlEncode[[validation-summary-errors]]\"><ul><li style=\"display:none\"></li>" +
|
|
||||||
Environment.NewLine +
|
|
||||||
"</ul></div>",
|
|
||||||
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -576,6 +566,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelState.AddModelError(string.Empty, "Error for root");
|
||||||
helper.ViewData.ModelState.AddModelError("Property1", "Error for Property1");
|
helper.ViewData.ModelState.AddModelError("Property1", "Error for Property1");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -585,7 +576,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"<div class=\"HtmlEncode[[validation-summary-errors]]\"><span>HtmlEncode[[Custom Message]]</span>" +
|
"<div class=\"HtmlEncode[[validation-summary-errors]]\"><span>HtmlEncode[[Custom Message]]</span>" +
|
||||||
Environment.NewLine +
|
Environment.NewLine +
|
||||||
"<ul><li style=\"display:none\"></li>" + Environment.NewLine +
|
"<ul><li>HtmlEncode[[Error for root]]</li>" + Environment.NewLine +
|
||||||
"</ul></div>",
|
"</ul></div>",
|
||||||
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
||||||
}
|
}
|
||||||
|
|
@ -633,6 +624,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelState.AddModelError(string.Empty, "Error for root");
|
||||||
helper.ViewData.ModelState.AddModelError("Property1", "Error for Property1");
|
helper.ViewData.ModelState.AddModelError("Property1", "Error for Property1");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -642,7 +634,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"<div class=\"HtmlEncode[[validation-summary-errors]]\"><div>HtmlEncode[[Custom Message]]</div>" +
|
"<div class=\"HtmlEncode[[validation-summary-errors]]\"><div>HtmlEncode[[Custom Message]]</div>" +
|
||||||
Environment.NewLine +
|
Environment.NewLine +
|
||||||
"<ul><li style=\"display:none\"></li>" + Environment.NewLine +
|
"<ul><li>HtmlEncode[[Error for root]]</li>" + Environment.NewLine +
|
||||||
"</ul></div>",
|
"</ul></div>",
|
||||||
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
||||||
}
|
}
|
||||||
|
|
@ -652,16 +644,20 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelState.AddModelError(string.Empty, "Error for root");
|
||||||
helper.ViewData.ModelState.AddModelError("Property1", "Error for Property1");
|
helper.ViewData.ModelState.AddModelError("Property1", "Error for Property1");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var validationSummaryResult = helper.ValidationSummary(excludePropertyErrors: true, message: "Custom Message", htmlAttributes: new { attr = "value" });
|
var validationSummaryResult = helper.ValidationSummary(
|
||||||
|
excludePropertyErrors: true,
|
||||||
|
message: "Custom Message",
|
||||||
|
htmlAttributes: new { attr = "value" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"<div attr=\"HtmlEncode[[value]]\" class=\"HtmlEncode[[validation-summary-errors]]\"><span>HtmlEncode[[Custom Message]]</span>" +
|
"<div attr=\"HtmlEncode[[value]]\" class=\"HtmlEncode[[validation-summary-errors]]\"><span>HtmlEncode[[Custom Message]]</span>" +
|
||||||
Environment.NewLine +
|
Environment.NewLine +
|
||||||
"<ul><li style=\"display:none\"></li>" + Environment.NewLine +
|
"<ul><li>HtmlEncode[[Error for root]]</li>" + Environment.NewLine +
|
||||||
"</ul></div>",
|
"</ul></div>",
|
||||||
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
HtmlContentUtilities.HtmlContentToString(validationSummaryResult));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ namespace RazorWebSite.Controllers
|
||||||
offset: TimeSpan.FromHours(0))
|
offset: TimeSpan.FromHours(0))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ModelState.AddModelError(string.Empty, "A model error occurred.");
|
||||||
ModelState.AddModelError("Error", "An error occurred.");
|
ModelState.AddModelError("Error", "An error occurred.");
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
@ -42,6 +43,7 @@ namespace RazorWebSite.Controllers
|
||||||
offset: TimeSpan.FromHours(0))
|
offset: TimeSpan.FromHours(0))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ModelState.AddModelError(string.Empty, "A model error occurred.");
|
||||||
ModelState.AddModelError("Error", "An error occurred.");
|
ModelState.AddModelError("Error", "An error occurred.");
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue