Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
/MvcPublic archive

Commitf8f9bbc

Browse files
committed
Addnull check forModelStateEntry.Children
-#4989
1 parent6a9a753 commitf8f9bbc

File tree

4 files changed

+196
-9
lines changed

4 files changed

+196
-9
lines changed

‎src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/ValidationHelpers.cs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
usingSystem.Collections.Generic;
55
usingSystem.Diagnostics;
6-
usingSystem.Linq;
76
usingMicrosoft.AspNetCore.Mvc.ModelBinding;
87

98
namespaceMicrosoft.AspNetCore.Mvc.ViewFeatures.Internal
@@ -90,7 +89,7 @@ private static void Visit(
9089
ModelMetadatametadata,
9190
List<ModelStateEntry>orderedModelStateEntries)
9291
{
93-
if(metadata.ElementMetadata!=null)
92+
if(metadata.ElementMetadata!=null&&modelStateEntry.Children!=null)
9493
{
9594
foreach(varindexEntryinmodelStateEntry.Children)
9695
{

‎test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,21 @@ public static ViewContext GetViewContext(
6565
IHtmlGeneratorhtmlGenerator,
6666
IModelMetadataProvidermetadataProvider)
6767
{
68-
varactionContext=newActionContext(newDefaultHttpContext(),newRouteData(),newActionDescriptor());
69-
varviewData=newViewDataDictionary(metadataProvider)
68+
returnGetViewContext(model,htmlGenerator,metadataProvider,modelState:newModelStateDictionary());
69+
}
70+
71+
publicstaticViewContextGetViewContext(
72+
objectmodel,
73+
IHtmlGeneratorhtmlGenerator,
74+
IModelMetadataProvidermetadataProvider,
75+
ModelStateDictionarymodelState)
76+
{
77+
varactionContext=newActionContext(
78+
newDefaultHttpContext(),
79+
newRouteData(),
80+
newActionDescriptor(),
81+
modelState);
82+
varviewData=newViewDataDictionary(metadataProvider,modelState)
7083
{
7184
Model=model,
7285
};

‎test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ValidationSummaryTagHelperTest.cs‎

Lines changed: 171 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,149 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
2323
{
2424
publicclassValidationSummaryTagHelperTest
2525
{
26+
publicstaticTheoryData<ModelStateDictionary>ProcessAsync_GeneratesExpectedOutput_WithNoErrorsData
27+
{
28+
get
29+
{
30+
varemptyModelState=newModelStateDictionary();
31+
32+
varmodelState=newModelStateDictionary();
33+
SetValidModelState(modelState);
34+
35+
returnnewTheoryData<ModelStateDictionary>
36+
{
37+
emptyModelState,
38+
modelState,
39+
};
40+
}
41+
}
42+
43+
[Theory]
44+
[MemberData(nameof(ProcessAsync_GeneratesExpectedOutput_WithNoErrorsData))]
45+
publicasyncTaskProcessAsync_GeneratesExpectedOutput_WithNoErrors(
46+
ModelStateDictionarymodelState)
47+
{
48+
// Arrange
49+
varexpectedTagName="not-div";
50+
varmetadataProvider=newTestModelMetadataProvider();
51+
varhtmlGenerator=newTestableHtmlGenerator(metadataProvider);
52+
53+
varexpectedPreContent="original pre-content";
54+
varexpectedContent="original content";
55+
vartagHelperContext=newTagHelperContext(
56+
allAttributes:newTagHelperAttributeList(
57+
Enumerable.Empty<TagHelperAttribute>()),
58+
items:newDictionary<object,object>(),
59+
uniqueId:"test");
60+
varoutput=newTagHelperOutput(
61+
expectedTagName,
62+
attributes:newTagHelperAttributeList
63+
{
64+
{"class","form-control"}
65+
},
66+
getChildContentAsync:(useCachedResult,encoder)=>
67+
{
68+
vartagHelperContent=newDefaultTagHelperContent();
69+
tagHelperContent.SetContent("Something");
70+
returnTask.FromResult<TagHelperContent>(tagHelperContent);
71+
});
72+
output.PreContent.SetContent(expectedPreContent);
73+
output.Content.SetContent(expectedContent);
74+
output.PostContent.SetContent("Custom Content");
75+
76+
varmodel=newModel();
77+
varviewContext=TestableHtmlGenerator.GetViewContext(model,htmlGenerator,metadataProvider,modelState);
78+
varvalidationSummaryTagHelper=newValidationSummaryTagHelper(htmlGenerator)
79+
{
80+
ValidationSummary=ValidationSummary.All,
81+
ViewContext=viewContext,
82+
};
83+
84+
// Act
85+
awaitvalidationSummaryTagHelper.ProcessAsync(tagHelperContext,output);
86+
87+
// Assert
88+
Assert.Equal(2,output.Attributes.Count);
89+
varattribute=Assert.Single(output.Attributes, attr=>attr.Name.Equals("class"));
90+
Assert.Equal("form-control validation-summary-valid",attribute.Value);
91+
attribute=Assert.Single(output.Attributes, attr=>attr.Name.Equals("data-valmsg-summary"));
92+
Assert.Equal("true",attribute.Value);
93+
Assert.Equal(expectedPreContent,output.PreContent.GetContent());
94+
Assert.Equal(expectedContent,output.Content.GetContent());
95+
Assert.Equal(
96+
$"Custom Content<ul><li style=\"display:none\"></li>{Environment.NewLine}</ul>",
97+
output.PostContent.GetContent());
98+
Assert.Equal(expectedTagName,output.TagName);
99+
}
100+
101+
[Theory]
102+
[InlineData(ValidationSummary.All)]
103+
[InlineData(ValidationSummary.ModelOnly)]
104+
publicasyncTaskProcessAsync_GeneratesExpectedOutput_WithModelError(ValidationSummaryvalidationSummary)
105+
{
106+
// Arrange
107+
varexpectedError="I am an error.";
108+
varexpectedTagName="not-div";
109+
varmetadataProvider=newTestModelMetadataProvider();
110+
varhtmlGenerator=newTestableHtmlGenerator(metadataProvider);
111+
112+
varvalidationSummaryTagHelper=newValidationSummaryTagHelper(htmlGenerator)
113+
{
114+
ValidationSummary=validationSummary,
115+
};
116+
117+
varexpectedPreContent="original pre-content";
118+
varexpectedContent="original content";
119+
vartagHelperContext=newTagHelperContext(
120+
allAttributes:newTagHelperAttributeList(
121+
Enumerable.Empty<TagHelperAttribute>()),
122+
items:newDictionary<object,object>(),
123+
uniqueId:"test");
124+
varoutput=newTagHelperOutput(
125+
expectedTagName,
126+
attributes:newTagHelperAttributeList
127+
{
128+
{"class","form-control"}
129+
},
130+
getChildContentAsync:(useCachedResult,encoder)=>
131+
{
132+
vartagHelperContent=newDefaultTagHelperContent();
133+
tagHelperContent.SetContent("Something");
134+
returnTask.FromResult<TagHelperContent>(tagHelperContent);
135+
});
136+
output.PreContent.SetContent(expectedPreContent);
137+
output.Content.SetContent(expectedContent);
138+
output.PostContent.SetContent("Custom Content");
139+
140+
varmodel=newModel();
141+
varviewContext=TestableHtmlGenerator.GetViewContext(model,htmlGenerator,metadataProvider);
142+
validationSummaryTagHelper.ViewContext=viewContext;
143+
144+
varmodelState=viewContext.ModelState;
145+
SetValidModelState(modelState);
146+
modelState.AddModelError(string.Empty,expectedError);
147+
148+
// Act
149+
awaitvalidationSummaryTagHelper.ProcessAsync(tagHelperContext,output);
150+
151+
// Assert
152+
Assert.InRange(output.Attributes.Count,low:1,high:2);
153+
varattribute=Assert.Single(output.Attributes, attr=>attr.Name.Equals("class"));
154+
Assert.Equal("form-control validation-summary-errors",attribute.Value);
155+
Assert.Equal(expectedPreContent,output.PreContent.GetContent());
156+
Assert.Equal(expectedContent,output.Content.GetContent());
157+
Assert.Equal(
158+
$"Custom Content<ul><li>{expectedError}</li>{Environment.NewLine}</ul>",
159+
output.PostContent.GetContent());
160+
Assert.Equal(expectedTagName,output.TagName);
161+
}
162+
26163
[Fact]
27-
publicasyncTaskProcessAsync_GeneratesExpectedOutput()
164+
publicasyncTaskProcessAsync_GeneratesExpectedOutput_WithPropertyErrors()
28165
{
29166
// Arrange
167+
varexpectedError0="I am an error.";
168+
varexpectedError2="I am also an error.";
30169
varexpectedTagName="not-div";
31170
varmetadataProvider=newTestModelMetadataProvider();
32171
varhtmlGenerator=newTestableHtmlGenerator(metadataProvider);
@@ -59,23 +198,30 @@ public async Task ProcessAsync_GeneratesExpectedOutput()
59198
output.Content.SetContent(expectedContent);
60199
output.PostContent.SetContent("Custom Content");
61200

62-
Modelmodel=null;
201+
varmodel=newModel();
63202
varviewContext=TestableHtmlGenerator.GetViewContext(model,htmlGenerator,metadataProvider);
64203
validationSummaryTagHelper.ViewContext=viewContext;
65204

205+
varmodelState=viewContext.ModelState;
206+
SetValidModelState(modelState);
207+
modelState.AddModelError(key:$"{nameof(Model.Strings)}[0]",errorMessage:expectedError0);
208+
modelState.AddModelError(key:$"{nameof(Model.Strings)}[2]",errorMessage:expectedError2);
209+
66210
// Act
67211
awaitvalidationSummaryTagHelper.ProcessAsync(tagHelperContext,output);
68212

69213
// Assert
70214
Assert.Equal(2,output.Attributes.Count);
71215
varattribute=Assert.Single(output.Attributes, attr=>attr.Name.Equals("class"));
72-
Assert.Equal("form-control validation-summary-valid",attribute.Value);
216+
Assert.Equal("form-control validation-summary-errors",attribute.Value);
73217
attribute=Assert.Single(output.Attributes, attr=>attr.Name.Equals("data-valmsg-summary"));
74218
Assert.Equal("true",attribute.Value);
75219
Assert.Equal(expectedPreContent,output.PreContent.GetContent());
76220
Assert.Equal(expectedContent,output.Content.GetContent());
77-
Assert.Equal("Custom Content<ul><li style=\"display:none\"></li>"+Environment.NewLine+"</ul>",
78-
output.PostContent.GetContent());
221+
Assert.Equal(
222+
$"Custom Content<ul><li>{expectedError0}</li>{Environment.NewLine}"+
223+
$"<li>{expectedError2}</li>{Environment.NewLine}</ul>",
224+
output.PostContent.GetContent());
79225
Assert.Equal(expectedTagName,output.TagName);
80226
}
81227

@@ -339,9 +485,29 @@ private static ViewContext CreateViewContext()
339485
newHtmlHelperOptions());
340486
}
341487

488+
privatestaticvoidSetValidModelState(ModelStateDictionarymodelState)
489+
{
490+
modelState.SetModelValue(key:nameof(Model.Empty),rawValue:null,attemptedValue:null);
491+
modelState.SetModelValue(key:$"{nameof(Model.Strings)}[0]",rawValue:null,attemptedValue:null);
492+
modelState.SetModelValue(key:$"{nameof(Model.Strings)}[1]",rawValue:null,attemptedValue:null);
493+
modelState.SetModelValue(key:$"{nameof(Model.Strings)}[2]",rawValue:null,attemptedValue:null);
494+
modelState.SetModelValue(key:nameof(Model.Text),rawValue:null,attemptedValue:null);
495+
496+
foreach(varkeyinmodelState.Keys)
497+
{
498+
modelState.MarkFieldValid(key);
499+
}
500+
}
501+
342502
privateclassModel
343503
{
344504
publicstringText{get;set;}
505+
506+
publicstring[]Strings{get;set;}
507+
508+
// Exists to ensure #4989 does not regress. Issue specific to case where collection has a ModelStateEntry
509+
// but no element does.
510+
publicbyte[]Empty{get;set;}
345511
}
346512
}
347513
}

‎test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Rendering/HtmlHelperValidationSummaryTest.cs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,8 @@ private void AddMultipleErrors(ModelStateDictionary modelState)
672672
modelState.AddModelError("Property3.Property2","This is an error for Property3.Property2.");
673673
modelState.AddModelError("Property3.OrderedProperty3","This is an error for Property3.OrderedProperty3.");
674674
modelState.AddModelError("Property3.OrderedProperty2","This is an error for Property3.OrderedProperty2.");
675+
modelState.SetModelValue("Property3.Empty",rawValue:null,attemptedValue:null);
676+
modelState.MarkFieldValid("Property3.Empty");
675677

676678
varprovider=newEmptyModelMetadataProvider();
677679
varmetadata=provider.GetMetadataForProperty(typeof(ValidationModel),nameof(ValidationModel.Property3));
@@ -712,6 +714,9 @@ private void AddOrderedErrors(ModelStateDictionary modelState)
712714

713715
modelState.AddModelError("OrderedProperty1","This is an error for OrderedProperty1.");
714716
modelState.AddModelError("OrderedProperty2","This is yet-another error for OrderedProperty2.");
717+
718+
modelState.SetModelValue("Empty",rawValue:null,attemptedValue:null);
719+
modelState.MarkFieldValid("Empty");
715720
}
716721

717722
privateclassValidationModel
@@ -738,6 +743,10 @@ private class OrderedModel
738743
publicstringOrderedProperty2{get;set;}
739744
[Display(Order=23)]
740745
publicstringOrderedProperty1{get;set;}
746+
747+
// Exists to ensure #4989 does not regress. Issue specific to case where collection has a ModelStateEntry
748+
// but no element does.
749+
publicbyte[]Empty{get;set;}
741750
}
742751

743752
privateclassModelWithCollection

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp