Custom error messages with validation message tag helper #8035 #8087
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very close. And, yes, needs tests.
Separately, please rebase your branch on our release/2.2
. Although not messing up the comparison, 6 extra commits are visible.
@@ -71,11 +71,13 @@ public ValidationMessageTagHelper(IHtmlGenerator generator) | |||
}; | |||
} | |||
|
|||
var childContent = await output.GetChildContentAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set childContent
to null
if output.IsContentModified
; the GetChildContentAsync()
call is expensive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sure.
var tagBuilder = Generator.GenerateValidationMessage( | ||
ViewContext, | ||
For.ModelExplorer, | ||
For.Name, | ||
message: null, | ||
message: childContent.IsEmptyOrWhiteSpace ? null : childContent.GetContent(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This condition also needs to check output.IsContentModified
and to pass message: null
in that case.
By the way, test failures are caused by not checking |
@@ -89,7 +91,7 @@ public ValidationMessageTagHelper(IHtmlGenerator generator) | |||
// We check for whitespace to detect scenarios such as: | |||
// <span validation-for="Name"> | |||
// </span> | |||
var childContent = await output.GetChildContentAsync(); | |||
|
|||
if (childContent.IsEmptyOrWhiteSpace) | |||
{ | |||
// Provide default message text (if any) since there was nothing useful in the Razor source. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should have mentioned:
- This comment is no longer correct since message may have come from the Razor source now
- The
else
block starting at line 103 is no longer needed - The comment above about whitespace belongs above the
GenerateValidationMessage(...)
call
I suspect this block could now be narrowed to:
if (!output.IsContentModified && tagBuilder.HasInnerHtml))
{
output.Content.SetHtmlContent(tagBuilder.InnerHtml);
}
Hi @dougbu But I'm able to run tests from CMD line. I'm getting following error, when I run tests on visual studio. [17-07-2018 09:01:26 PM Informational] ------ Run test started ------
|
@kishanAnem this likely means your |
Thank you very much. It worked... 👍 |
Hi @dougbu commit title is misleading sorry for that tried to revert. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks better but lost the IsEmptyOrWhiteSpace
check
@@ -71,37 +71,29 @@ public ValidationMessageTagHelper(IHtmlGenerator generator) | |||
}; | |||
} | |||
|
|||
string message = null; | |||
TagHelperContent tagHelperContent = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this outside the next block i.e. just use var tagHelperContent = await output.GetChildContentAsync();
if (!output.IsContentModified) | ||
{ | ||
tagHelperContent = await output.GetChildContentAsync(); | ||
message = tagHelperContent.GetContent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check tagHelperContent.IsEmptyOrWhiteSpace
before updating message
.
var tagBuilder = Generator.GenerateValidationMessage( | ||
ViewContext, | ||
For.ModelExplorer, | ||
For.Name, | ||
message: null, | ||
message: output.IsContentModified ? null : message, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just message
since it's null
if output.IsContentModified
@@ -358,16 +358,16 @@ public class ValidationMessageTagHelperTest | |||
|
|||
[Theory] | |||
[InlineData("Content of validation message", "Content of validation message")] | |||
[InlineData("\r\n \r\n", "New HTML")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should work as it did before.
|
||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict); | ||
var setup = generator | ||
.Setup(mock => mock.GenerateValidationMessage( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This setup should confirm the expected message
is passed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
validationMessageTagHelper.ViewContext = viewContext; | ||
|
||
// Act | ||
validationMessageTagHelper.ProcessAsync(context, output).Wait(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're calling ProcessAsync(...)
, use await
and change the method's signature to include async Task
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost…
tag: null, | ||
htmlAttributes: htmlAttributes); | ||
|
||
if (tagBuilder != null) | ||
{ | ||
output.MergeAttributes(tagBuilder); | ||
|
||
// Do not update the content if another tag helper targeting this element has already done so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore this comment
if (!output.IsContentModified) | ||
{ | ||
// We check for whitespace to detect scenarios such as: | ||
// <span validation-for="Name"> | ||
// </span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore this comment but above line 78
// </span> | ||
var childContent = await output.GetChildContentAsync(); | ||
if (childContent.IsEmptyOrWhiteSpace) | ||
if (string.IsNullOrWhiteSpace(message) && tagBuilder.HasInnerHtml) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get rid of the string.IsNullOrWhiteSpace(message)
check and the else
because whitespace should be impossible given the earlier tagHelperContent.IsEmptyOrWhiteSpace
check and the IHtmlGenerator
has already done the right thing with message
. This block should just be
if (!output.IsContentModified && tagBuilder.HasInnerHtml)
{
output.Content.SetHtmlContent(tagBuilder.InnerHtml);
}
@@ -364,10 +364,11 @@ public class ValidationMessageTagHelperTest | |||
string expectedOutputContent) | |||
{ | |||
// Arrange | |||
var tagBuilder = new TagBuilder("span2"); | |||
var tagBuilder = new TagBuilder("span"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking more closely at these tests, I see ProcessAsync_MergesTagBuilderFromGenerateWithoutValidationMessage()
should be redundant. Remove the new test and revert current changes to ProcessAsync_MergesTagBuilderFromGenerateValidationMessage(...)
. Then, add an expectedMessage
parameter and the right data values ("Content of validation message"
and null
) and use expectedMessage
in the Setup(...)
at line 379.
Don't add the ProcessAsync_MergesTagBuilderFromGenerateWithoutValidationMessage(...)
case ([InlineData(null, null, "New HTML")]
) here because there's a bug in DefaultTagHelperContent.IsEmptyOrWhiteSpaceCore()
. It returns false
when the only content is null
.
Congrats on unearthing that aspnet/Razor bug!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed aspnet/Razor#2497 and am doing a quick fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this happens with great support.
It.IsAny<ViewContext>(), | ||
It.IsAny<ModelExplorer>(), | ||
It.IsAny<string>(), | ||
"", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI we always use string.Empty
unless a constant is required
|
||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict); | ||
var setup = generator | ||
.Setup(mock => mock.GenerateValidationMessage( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
@kishanAnem please ( |
And, ignore the VSTS failure. Not sure why the |
Hi @dougbu , |
Hi @dougbu |
Hi @dougbu
I think I fixed this bug. Is this right way to fix?
If yes, I'll add test cases.