In previous article, we have discussed about the @bind
Razor directive attribute and how it can be used for binding the data. In this article, we are going to discuss another important aspect – the validations.
So, let’s get started !
The EditForm Component
Before discussing about the validations, let’s first try to understand more about the EditForm component. Basic idea is –
- EditForm component bound to a model ( a C# POCO class) that uses data annotations
- EditForm component may contain one or more Built-in input components
Let’s take an example from one of the previous posts where we have added “AddStudent.razor
” Blazor component. The code snippet is given below:
Below is the high level overview of the code:
- The EditForm component is rendered where the
<EditForm>
element appears. - We have created a private field,
studentModel
in the@code
block. - The field is assigned to EditForm.Model attribute.
- There are three children, the InputText components.
- Each InputText component has a
@bind-value
attribute, to bind a specific property of the model (which is assigned to EditForm.Model ). - The EditForm component also has a
submit
button. - The
HandleValidSubmit
method is assigned to OnValidSubmit. The handler is called if the form passes validation.
Also, there are no validations specified on the Student
model. Our Blazor component also does not have any component to show the error messages. We will see that in the coming sections.
Binding the form
As shown in the code snippet give above, the EditForm component can be bound to data using Model property of the component. The EditForm component internally creates EditContext based on the assigned model, to track which fields have been modified and current validation messages.
Alternatively, we can directly set the EditContext property on the EditForm component. The model cannot be directly assigned to the EditContext property. Basically, we need to create instance of EditContext class and pass the model to it as shown in the code snippet given below. This code is equivalent of the previous code snippet.
We can assign model to either an EditContext or a Model to an EditForm. Specifying both attributes would cause a runtime exception. Also, if we specify EditContext and its value is set to an expression which evaluates to null, then also a runtime exception is thrown.
Validating the Form Inputs
The standard way of validating the inputs is to specify the data annotation attributes on the model which is bound to the EditForm component. In the previous code snippet, I have not shown the Student class, but it has 3 string
properties – FirstName
, LastName
and Address
. It also has a DateTime
property, namely, CreatedOn
.
The Student class does not have any data annotations specified. So, let’s modify our model and let’s sepcify some validations via data annotations. Let’s say,
- FirstName and LastName fields are required and they should not have more than 50 characters.
- Address is not required, and it allows maximum 100 characters.
The modified class would look as given below.
If we just run the code as it is, without modifying the Blazor component, the application would not perform any validation. Why ?
Attaching Validations to the Form
To ensure that validation is being performed, we must specify the validation mechanism in the razor file. Let’s add the DataAnnotationsValidator component inside the form as shown below. The data annotations validator (DataAnnotationsValidator component) attaches validation support using data annotations.
Now, our model has data annotations and we also have specified the validator which attaches validation to the form. Now, if we run the program, and hit the submit button, without adding any input, the validation happens. The two textboxes are highlighted with red border. But validation messages do not appear. Why ?
Displaying the validation messages
There are basically two ways by which we can display the validation messages.
- ValidationSummary component can be placed inside the form and it will show comprehensive summary of all error messages once at the top of the form.
- the
ValidationMessage
component displays error messages for a single field.. So for every input field, we need to add oneValidationMessage
component. As it is one per input control, it needs us to specify the identity of the field via a C# expression.
If we specify both components, the errors will be shown at both places. Below is the modified code from the AddStudent.razor
component.
When we run the modified application and if there are any validation errors, we can see the error messages as shown in the below snapshot.
Customizing the error messages
Although the form above looks fine, there are still few things which need to be changed. For example, the error message for exceeding the maximum allowed length is really long and very generic. It may also be confusing to business users, if we keep the error message as it is.
Another issue is, the validation errors contain the model property name, rather than the field name used on the form. In our case, although the field name on the form and property names in model are almost the same (if we exclude the space between the words), but in some applications, they may be totally different.
So, what if we want to have custom field name or custom validation message ? In such cases, DisplayName property and ParsingErrorMessage template can be helpful.
The ParsingErrorMessage is supported only by two input controls – InputDate<TValue> and InputNumber<TValue>. It is used when the input provided by user contains any parsing error. It explains why this property is available only on these two input controls.
The DisplayName is available on all the input controls.
In case of many controls the error messages and display names are generated by data annotations and not by Blazor. In such cases, the error messages can be specified in the data annotation itself. We can also use DisplayAttribute to specify the display name of the field, which would be used in the validation error message.
With this modified model, the error messages would also change as shown in the snapshot given below.
So, that’s all about input controls and their validations. I hope you find this information helpful. Let me know your thoughts.