I leave here two solutions that have not been mentioned before. One dogmatic and one pragmatic, but depending on what you are looking for both solutions can be interesting. With both you will solve the problem in 1 minute.
Proof of concept:
Brief introduction (really necessary):
Microsoft uses jquery-validation to perform client-side validation, and has extended the functionality of this library with its own jquery-validation-unobtrusive library.
If you go to the wwwroot/lib/jquery-validation-unobtrusive folder within the project you will find that within this library are rules that add classes such as “input-validation-error”.
Solution 1:
If we inspect the uses of, we see that “errorClass” is first queried from the options, and if it does not exist, then “input-validation-error” is used by default.
The first solution is to generate the configuration in which we are the ones who indicate the name of “errorClass”.
Include the following script in your execution tree:
<script>
const settings = {
errorClass: 'is-invalid',
}
$.validator.unobtrusive.options = settings
</script>
Good place to do this would be at the end of your _ValidationScriptsPartial.cshtml file. Either way, you have to make sure that your script is executed after the inclusion of the jquery.validate.unobtrusive.js file.
Solution 2:
The solution is as simple as replacing the string “input-validation-error” with “is-invalid” (there are two places).
Why do I consider these solutions to be the cleanest and simplest?
There is no need to add Extensions, Helpers or magic Services that you have to rethink later (you always have to adjust the code, or update the .Net version, or include a new dev).
This solutions works transparently with any Razor project. The dev should not even notice this tweak. He should just write his Razor components.
It does not introduce weird rules with JS, which later in the execution chain can be difficult to debug.
It does not set up new styles, nor magic inheritances to solve the problem, which usually causes headaches when styles do not work properly.
Finally, this solution not only works for Bootstrap, it works for any stylesheet you want to use. It avoids name dependency with Microsoft defined classes (apparently, without being consistent in this aspect, so I don't see any good reason to keep using them).