Closed RichardBr closed 3 years ago
Thanks for contacting us. It looks like you're missing some logic to add the validation messages in the right place in Validation Context. Here is a sample which would help you with that: https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0#validator-components
Specifically, please see the part where it calls messageStore.Add
.
@SteveSandersonMS and @mkArtakMSFT - I am still unable to see what you are suggesting, I'm doing wrong/missing!
My validator component code, as shown below (CustomValidator.cs
), is copied straight out from https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0#validator-components. It is also the only place on that web page where code messageStore.Add
is mentioned
CustomValidator.cs
using System; using System.Collections.Generic;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms;
namespace BlazorTest1.Client.Shared { public class CustomValidator : ComponentBase { private ValidationMessageStore messageStore;
[CascadingParameter]
private EditContext CurrentEditContext { get; set; }
protected override void OnInitialized()
{
if (CurrentEditContext == null)
{
throw new InvalidOperationException(
$"{nameof(CustomValidator)} requires a cascading " +
$"parameter of type {nameof(EditContext)}. " +
$"For example, you can use {nameof(CustomValidator)} " +
$"inside an {nameof(EditForm)}.");
}
messageStore = new ValidationMessageStore(CurrentEditContext);
CurrentEditContext.OnValidationRequested += (s, e) =>
messageStore.Clear();
CurrentEditContext.OnFieldChanged += (s, e) =>
messageStore.Clear(e.FieldIdentifier);
}
public void DisplayErrors(Dictionary<string, List<string>> errors)
{
foreach (var err in errors)
{
messageStore.Add(CurrentEditContext.Field(err.Key), err.Value);
}
CurrentEditContext.NotifyValidationStateChanged();
}
public void ClearErrors()
{
messageStore.Clear();
CurrentEditContext.NotifyValidationStateChanged();
}
}
}
My next chunk of code, in `index.razor` (shown above in the original bug log), is **heavily based** on the code from [https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0#business-logic-validation](url) . The only real difference is that I have added an additional validation check...
...
if (starship.CaptainsName.Firstname != "James")
{
//errors.Add(nameof(starship.CaptainsName.Firstname), new List<string>() { "Firstname must be James" }); // does not work (as expected)!
errors.Add("CaptainsName.Firstname", new List<string>() { "Firstname must be James" });
}
...
When I don't use a complex model property, my solution works!
Please explain before closing this issue.
Thank you.
errors.Add("CaptainsName.Firstname", ... ... messageStore.Add(CurrentEditContext.Field(err.Key), err.Value);
This is a problem. This adds the message under a field called CaptainsName.Firstname
, which is absolutely wrong since none of the properties have that name (with a dot in the middle - it's not even a valid C# property name). The code should look like the following:
messageStore.Add(FieldIdentifier.Create(starship.CaptainsName, "Firstname"), "Your message goes here");
... or:
messageStore.Add(FieldIdentifier.Create(() => starship.CaptainsName.Firstname), "Your message goes here");
The field identifier is an objectInstance, propertyName
pair. This is how it gets matched up with an input that reads the same property from the same object instance.
@SteveSandersonMS - Beautiful solution that works perfectly. I'm so impressed with your answer, I am planning on asking the people, who are responsible for the doc at https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0#business-logic-validation to modify it to incorporate this approach. I feel it would help a lot of community members.
Describe the bug
The issue is I'm not able to get a validation message to show against a field. Although the error message does appear in the validation summary.
This issue is also further restricted to only complex model properties. The approach of using "ValidateComplexType", "ObjectGraphDataAnnotationsValidator" to resolve complex model property validation limitation does not help in this instance.
To Reproduce
The sample code below which I have created to demonstrate the problem is virtually ALL code from the Microsoft docs website (https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation). I have attached the complete source code solution. Simply rebuild the solution and run it to test. BlazorTest1.zip
New Ship Entry Form
Captain's Name
@message
Star Trek, ©1966-2019 CBS Studios, Inc. and Paramount Pictures
@code { private bool disabled; private string message; private string messageStyles = "visibility:hidden"; private CustomValidator customValidator; private Starship starship = new Starship() { ProductionDate = DateTime.UtcNow };
}
using System; using System.ComponentModel.DataAnnotations;
namespace BlazorTest1.Client.Shared { public class Starship { [Required] [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")] public string Identifier { get; set; }
}
namespace BlazorTest1.Client.Shared { public class PersonsName { public string Firstname { get; set; } public string Lastname { get; set; } } }