11

I am using ValidationMessage in a razor component to show validation message, like this:

<ValidationMessage For="@(() => ViewModel.CompanyNumber)" />

This generates this HTML code:

<div class="validation-message">The company number field is required.</div>

Is it possible to change the CSS-class? I want to use something else than validation-message. Adding class="myclass" is ignored by the controller. I've also tried with @attributes without success.

4 Answers 4

5
+50

With .NET5 they added functionality to customize the validation classes on the actual input-fields (which issue 8695 was about) by way of setting a FieldCssClassProvider to the edit context. But there still seems to be no way of customizing the classes of the ValidationSummary or ValidationMessage components

Snipped directly from the .NET 5 docs

var editContext = new EditContext(model);
editContext.SetFieldCssClassProvider(new MyFieldClassProvider());

...

private class MyFieldClassProvider : FieldCssClassProvider
{
    public override string GetFieldCssClass(EditContext editContext, 
        in FieldIdentifier fieldIdentifier)
    {
        var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();

        return isValid ? "good field" : "bad field";
    }
}

Using this will yield the below html for an invalid input. At least with this we can style the actual input elements. Just not the messages...

<input class="bad field" aria-invalid="">
<div class="validation-message">Identifier too long (16 character limit).</div>
Sign up to request clarification or add additional context in comments.

1 Comment

I completely missed that this was added to .NET 5! Thanks!!!
4

You can change the validation-message class inside the css file app.css inside the wwwroot. Or site.css in in earlier previews.

.validation-message {
    color: red;
}

The class is set in ValidationMessage.cs

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
    foreach (var message in CurrentEditContext.GetValidationMessages(_fieldIdentifier))
    {
        builder.OpenElement(0, "div");
        builder.AddMultipleAttributes(1, AdditionalAttributes);
        builder.AddAttribute(2, "class", "validation-message");
        builder.AddContent(3, message);
        builder.CloseElement();
    }
}

https://github.com/dotnet/aspnetcore/blob/master/src/Components/Web/src/Forms/ValidationMessage.cs

1 Comment

I guess that is the way to go for the current version. Not what I wanted but not too bad.
1

Why don't you just copy the code for ValidationMessage.cs and write in your own property? There is nothing special about this class except for capturing a Cascading Parameter. Just take this file and make your own with a slightly different name then add:

[Parameter] public string AdditionalClassNames {get;set;}

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
    foreach (var message in CurrentEditContext.GetValidationMessages(_fieldIdentifier))
    {
        builder.OpenElement(0, "div");
        builder.AddMultipleAttributes(1, AdditionalAttributes);
        builder.AddAttribute(2, "class", string.IsNullOrEmpty(AdditionalClassNames) ? "validation-message" : $"validation-message {AdditionalClassNames}");
        builder.AddContent(3, message);
        builder.CloseElement();
    }
}

https://github.com/dotnet/aspnetcore/blob/master/src/Components/Web/src/Forms/ValidationMessage.cs

EDIT

Even better, it's not sealed! Just use it as a base class for a new version and add what I mentioned above.

Comments

0

It is not possible in ASP.NET Core 3.1. Hopefully, it will be included in next major version, see this feature request:

https://github.com/dotnet/aspnetcore/issues/8695

5 Comments

You have this tagged for Blazor, if so can you use @attributes like the documentation outlines at learn.microsoft.com/en-us/aspnet/core/blazor/…?
No, I’ve tried @attributes too but that didn’t work either ☹
huh, I was able to get the attributes version going using the dictionary method they outline. Oddly though it would always add my class first, and then leave the original class in place.
@NikProtsman, I’ve just double checked and for me I can’t use @attributes to generate class on the ValidationMessage, but it works for other attributes.
You could just go in the source code, copy the ValidationMessage component and change the name of the class or create a parameter for the class name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.