We will learn how to create a form in a Blazor app. The form will support built-in client-side validations with the help of data annotations. We will implement a custom client-side validator for the form. We will also add a custom form validator component for business logic validation along with the client-side validator.
You can see a GIF showing the app in action at https://www.syncfusion.com/blogs/wp-content/uploads/2021/07/Creating-a-Student-Registartion-Form-in-Blazor-WebAssembly.gif
About Speker
Ankit Sharma is a Software Engineer, working with Cisco Systems and staying with his family at Samastipur, Bihar, India. He has over 7 years of extensive experience in Microsoft technologies including C#, ASP.NET, SQL Server and UI technologies such as JQuery, Angular and Blazor.
Ankit is a technical author and speaker and loves to contribute to the open-source community. He writes articles for multiple platforms, which include c-sharpcorner, Dzone, Medium, and freeCodeCamp. For his dedicated contribution to the developer’s community, he has been recognized as the Google Developer Expert for Angular and an Microsoft MVP for Developer Technologies. He is the author of Blazor Quick Start Guide and Learn C# Programming
Show More Show Less View Video Transcript
0:00
Hello everyone, my name is Ankit and today we are going to talk about Blazor forms and validations
0:07
So I am currently working with Cisco Systems as software engineer. I am an author and speaker. I am a GDE for Angular and a Microsoft MVP for developer technology
0:15
I also write blogs at various platforms including C sharp corner, free code camp, and I also have my personal blog at ankisharmablogs.com
0:22
You can go there and read blogs regarding .NET and frontend technologies such as Blazor and Angular
0:28
and Angular. So let us understand how Blazor allows us to use forms. We can create a form in Blazor
0:36
using the edit form component. The form validation can be implemented with the help of data annotations
0:42
So if you are coming from a .NET background, you are already aware of data annotations which we
0:47
used to have in our MVC. The same data annotations are carried over to Blazor and we are going to use
0:52
that to show the form validations. The edit form component in Blazor provides us three
0:59
methods to handle form submission. The first one is on submit so as the name suggests it will be
1:05
called when the form is submitted. Then we have on valid submit it will be invoked when form is
1:10
submitted and the form validations are passed. And finally we have on invalid submit it will
1:16
be invoked when the form is submitted but the form validations are failed
1:22
Blazor also allows us built-in components to receive and validate user inputs in a form
1:29
The input is validated during onChange event or when the form is submitted
1:34
So here you can see a list of built-in Blazor components provided
1:38
So we can use the input checkbox component and then it will be rendered as an input type
1:42
of checkbox. Similarly, we have input date component, which will be rendered as input type of date
1:48
Similarly, we have component for input file, input number, input radio, radio group, select, text box and text area
1:58
So we are going to use all these built-in components whenever we are going to create forms in Blazor
2:04
These built-in components will make our life easier as a Blazor developer where we can easily integrate the validations to the feeds
2:12
So we are going to see how it is done in the latter part of the talk where I am going to show the demo
2:18
So let us understand what is the edit context class. The edit context class holds metadata related to the data editing process such as fields
2:27
being modified and the validation messages. The edit form component creates a cascading value of type edit context and we can use
2:35
either the model attribute or the edit context attribute in the edit form component
2:40
Using both attribute at the same time results in a runtime error
2:43
So we are going to see this in example, how we can use a custom edit context
2:48
how we can customize our context to add custom form validation and how we can use inbuilt validation
2:58
in the edit form component. So in case of validation, there will be two types of validation
3:05
One will be the client side and one will be the server side. So in case of client side validation
3:10
the data annotations class already provides us with some inbuilt validation such as range required, etc
3:18
However, there are some scenarios which is not covered by built-in form validation attribute
3:24
Then in that case, we are going to create a custom form validation attribute
3:27
which will allow us to associate the validation logic to a model property in a Blazor application
3:33
For example, if you want that a username field cannot contain the word admin
3:38
then there is no inbuilt validator provided the data annotations class. So we are going to create a custom validator for that
3:49
Similarly, we have custom server-side validation. Once the client-side validation is successful
3:54
we will send the form data to a back-end server via an API call. The model validation is processed
4:00
on the server and then it will return an error state code if the validation fails
4:04
Then we can create a custom validator component to display error on the form field
4:08
based on the server side validation so for example if we are registering for a particular field sorry
4:15
if we are registering for a particular website then the username must be unique for example
4:20
gmail.com so we need to do validation on server side where we are going to send the data to the
4:26
back end the data will be matched through a list of users which is already registered to the our
4:34
system and then based on that it will return the errors or the availability of the user
4:40
So we are going to see this example also in our demo
4:44
So it's demo time, let's go to the Visual Studio. So here I have created a Blazor Vasm application
4:55
The application is already created and I hope that you guys are already aware how to create
4:59
a Blazor Vasm application. So the process which I'm going to show here will be same for Blazor server also with very
5:06
minor differences. Here I am using Blazor WebAssembly. So first of all here I have created a class called employee
5:14
So today we are going to create a registration form for employee
5:18
The form will accept the details of the employee and it will also it will show if the username
5:25
is available or not based on the validation. The first step is to add the fields
5:30
So, the first property which I have added is first name. Here, I have put two annotations
5:38
One is required, which says that this field is required. And second is the display
5:43
So this particular display attribute is used to show the name which will be displayed on
5:51
the screen when the error message is shown. So when the error message is shown for this required field, this particular value will
5:59
will be displayed at along with the text is required. So similarly, we are going to add a last name field
6:09
In case of last name also, we have added the required field and the display property
6:15
Then we have email In case of email we have added the required plus the email address validation So email address validation will check if there is a add symbol and the dot symbol
6:27
or not. So this will check for using inbuilt regax that the particular email structure is correct
6:40
or not. Then we have the user name field. It is a required field
6:44
And also we are going to create a custom validator over here
6:48
So we will be adding that validator also after some time. Then we have a password field and the confirm password field
6:57
So in the password field, along with the required field, we are also added a regular expression
7:01
to check the strength of the password. So here you can see that I have added a error message
7:07
which says that passwords should have minimum eight characters, at least one uppercase, one lowercase, and one number
7:14
This particular check is done by this regular expression. So we are using the regular expression check
7:21
Similarly, we have other field called confirm password. This also contains the required
7:27
plus the display name and rotation. And also it is using a compare and rotation
7:34
to compare with the password field. So it will check if the password field value
7:38
and the confirm password field value matches are not. Otherwise it will show the error message
7:42
that the password and confirm password field not match. And finally we have added a field called gender which has only
7:53
required annotation. Then we'll add constructors when we slice all the fields
7:59
So this is all about our class. Then we will add a username validation attribute
8:07
So here you can see that we have added a username validation class which is
8:10
inheriting from the validation attribute class and we have overridden the is valid function of this
8:17
particular class. Now we are going to add our logic over here. So here this particular function will
8:27
accept the value for that particular field and also the validation context class. Here we are
8:32
going to check if the value does not contain the word admin. So we are going to put a check that
8:38
that the user name field should not contain the word admin in it
8:42
So this is the check for that. If the value for that particular field does not have the word admin in it
8:48
then we will return null, which means it is successful. Else, we are going to return a new object of type validation result
8:54
And here we are providing a custom error message, which says that the user name cannot contain the word admin
9:00
And here we are providing a list of a object of type list
9:06
for validation context of member name. Now, since we have added the logic for username validation
9:11
which is our custom class, we are going to use this over here
9:18
That is how we can create a custom client side validation for our field
9:22
So whenever we create a form, this particular username validation attribute will be invoked on our username field
9:30
and it will check the value over here. And if the username contains the word admin
9:35
our error message will be shown. Now, here we have created a controller
9:41
called employee controller. Here I will be adding a post method. At this point of time, you can see that
9:49
we have created a list of type string for username list and in the constructor, I have added three dummy values
9:57
Now, inside this post method, we will accept an object of type employee
10:01
and we will check if the username list this particular list contains the value which is in the username fit
10:09
There is a caution you have to note over here is that for the demo purpose
10:14
I have added this value as a dummy value. Ideally, at this point of time inside this post method
10:21
you should do a database call to fetch the list of users from your database
10:25
and then match against that particular value. But for demo purpose, for this particular session only
10:32
I have just used a dummy list over here. Now, if the username is already available in our database
10:39
in our list, then we will add an error to that particular field
10:44
which is employed at our username. And then we'll provide a custom message over here
10:48
which says that this username is not available. And then we will return the bad request
10:52
Else, if everything is successful, we'll return the OK request over here
10:58
Now, we have, this is a custom server side validation, which means we are sending the data to the server
11:06
via an API call. The server is doing all the validation, and then it is returning an error message to the client side
11:13
Now, since server is returning an error message to the client side, then the client
11:17
need to handle that particular error message as well. And the client need to show that error message
11:23
in a good format to the user. they have to show that error message properly on that particular field
11:30
For example, this says that user name is not available, then this error message should
11:35
be shown corresponding to the user name field, not corresponding to the complete form
11:40
So for that, we are going to create a custom form validator component
11:45
So this custom form validator component is created in the client project of our application
11:52
And here I have created a cascading parameter of type edit context
11:56
And I have also created a validation message store. Inside on any slice lifecycle hook, we are going to check if current edit context is null
12:04
or not. If it is null, then we are going to throw an exception. Else we are going to initialize the validation message store
12:11
And then we are going to check if in case of validation request, we are going to clear
12:15
the validation message store. In case of field change also, we are going to clear the validation message store
12:22
This particular function display form errors is very important function. It will accept a dictionary of type string and list of string
12:32
And in this particular function, we are going to iterate over that dictionary
12:37
And then we are going to add our field name and the error message into our validation message store So in that dictionary which we receive from our HTTP call
12:50
so when we do an HTTP call and we get an error message, it will come in the form of dictionary
12:54
and we are going to add that to our validation message store over here
12:59
This particular function display form error will be called from our component
13:03
and the key will be the field name for the form field name and the error value will be the value
13:10
will be the errors now and then we'll call the notify validation state change to notify all our
13:14
listeners for that finally similarly we have a clear forms error function which will clear all
13:22
the which will clear the validation message store and again update notify the edit context
13:27
I have created a register employee registration component. Inside this employee registration component, I have injected the HTTP client to make the
13:39
HTTP call. I have injected the logger to log the messages. Then we have created an instance for custom form validator and I have created a function
13:48
called register employee. Inside the register employee, first of all, we are going to call the clear forms error
13:54
So it will call this particular clear form and it will clear out all the error message
13:59
for that particular form. Then we are going to, inside the try block, we are going to do the HTTP call
14:06
So here you can see that we are making the API call to our backend
14:10
It is a post call and we are passing the object, which is of type employee
14:14
This particular employee object will be binded to our form in the HTML
14:19
And then as we change the value in the form, it will be a two way binding
14:23
this employee object will be updated and when we click on the form submit this register
14:28
employee function will be called and inside this register employee function we are going
14:32
to do the post call to our back end. Then we will see if there are any errors and we are receiving the error in form of a dictionary
14:45
Now here we are going to check if the status code is bad request and error count is greater
14:50
than zero then we are going to call the display form errors and we are going to send our error
14:55
dictionary to that function and then we are going to throw the exception else if there are no error
15:00
we are going to set this particular is registration successful property to true which is used to show
15:06
a success message on the screen and then we are going to log information that the registration is
15:10
successful this information will be shown in our browser console and inside the catch we are going
15:16
to log the error in our browser console. Finally, in the razor file we have added the root for the
15:25
page and then we have created the base class and this is just a basic bootstrap card. So I have
15:32
created a bootstrap card to show the form. On the top I have checked if the registration is successful
15:36
we are going to show alert that registration is successful. So the point of interest is this
15:41
edit form component so as I told you that edit form component is used to display the form on our
15:49
for our blazer application so here this edit form component will accept a parameter of type
15:55
parameter model which we will bind to model so this is of object employee which we have created
16:01
over here which is created over here then on valid submit which means this form when this
16:11
form will be submitted only when the client side validation is successful we are going to call the
16:15
register employee method then inside that we have written data annotation validator
16:20
component so this will invoke all our data annotation validators which we have defined
16:27
in our model and here we have used custom form validator component which we
16:32
have created over here so you can see that this custom form validator is
16:36
inheriting from a component base class therefore this will act as a component
16:40
for a Blazor application therefore we have added that and we have passed the
16:44
reference as custom form validator instance which we have created in our
16:49
component over here let me add the fields so first of all we are going to
16:56
the first name field. Here you can see that we have used the input text component. So if you
17:03
remember a few minutes back we discussed that Blazor provides us with few of the inbuilt components
17:11
to handle the form field. So input text is one of them. So we are going to use the input text over
17:16
here and we are binding it to the employee.firstname property and we are using validation
17:23
message component to display the error message for that particular field which is employee.firstname
17:29
so this validation message will be invoked if there are any kind of errors shown on the
17:34
any kind of error happens in for this particular field similarly we will add the last name field
17:40
inside last name also we have added an input text which is of type text box and we have
17:44
binded it to the last name property of our employee class and inside the validation message
17:49
we have also used we have binded to the employee dot last name similarly we have the email field
17:58
and email field is again using the input text component then we have the username field
18:07
inside the username field again we have used input text component and we have used validation
18:10
message component to bind it to the employee dot username so if you remember for username we have
18:16
used a custom username validation attribute. So even in case of the inbuilt error attribute
18:25
or the custom error attribute, if any one of them fails, this particular validation message component
18:31
will be invoked and the error message will be shown. Then we have the password field over here
18:39
So in case of password field, you can see that we have used input type text of type password
18:46
so that the field will be masked. Similarly, for confirm password, we have used the same property
18:51
and we have binded this field to employee.password and this to employee.confirm password
18:58
Finally we have the gender field So gender will be a dropdown So here we have used input select inbuilt component of Blazor which is provided by the Blazor and here we are showing three options One select
19:11
gender for the values empty then male and female and the validation message will be of employee.gender
19:17
At the end we have a register button which is of type submit. This is very important to understand
19:22
that the button should be of type submit then only form will be submitted and this particular
19:27
on valid submit function will be invoked. So let us run this application and then see it in action
19:45
So our application is launched
19:55
I have already added a register employee link in our menu bar
20:00
So this is our form. We are using a bootstrap card. So it is showing the title at the top
20:04
And here we have the field first name, last name, email, username, password, confirmed
20:08
password and gender. Gender has the two field, male and female. If I click on the register button at this point of time, it will show me all the client
20:17
side validation message. Now let us see this. You see the value over here, the first name field is required
20:24
This particular value first name is coming from our employee class. So if you go to the employee class, here you can see that we have added a display name
20:34
equals to first name. So this particular value first name is shown over here
20:39
That is how the display name is binded. This particular name, first name is coming from our label over here
20:48
So don't get confused between both of the value is same, but they are coming from two different places
20:54
So you can see all the required field validations are shown over here
20:58
So let us add the first name. So I add the first name. Here the last name
21:03
Now email field is required. Let us add some value over here. If I navigate to another field, it will say that email field is not a valid email address
21:11
This particular error message is shown via, where is that, email field inside the
21:21
email field we have added an email address validation so this is how it is
21:26
handled, email field is not a valid email address. So let me add a valid email address over here. Now username, so username field is required if I use the
21:35
word admin and navigate to another field you can see that immediately it shows
21:40
the error that user name cannot contain the word admin which is what we have this defined over here
21:46
in our username validation over here that username cannot contain the word admin so this same error
21:52
message is shown over here now this is checking for sub string so if i use admin user i get the
21:58
same error message so i cannot use the word admin in any form so i have to use some other name let's
22:04
say so this client side error validation is gone the field is green the password so i use
22:10
the password as like this. When I move out it shows that the password should have minimum
22:14
eight characters at least one uppercase, one lowercase and one number so I need to update that
22:22
Similarly, if I give wrong value it will say that the password and confirm password field do not match
22:30
So how this is working? This is working from this particular compare attribute. So compare attribute
22:36
will check if the password field and the confirm password field is matched or not
22:40
So let me remove that and update it. Now finally gender so it has only required for validation so I select mail
22:49
and click on register. Now at this point of time note that I have used the username as Ankit
22:54
If I click on the register button there is an API call happening to the back end and if you remember
22:59
in our controller we have also added the value Ankit over here. So this particular check will
23:05
fail this if condition will check that the this if condition will check that
23:10
particular username already exists and it will add a error to our model and
23:15
error says this username is not available the same error is shown over
23:19
here so this is how the server side validation is done another point to note
23:23
here is that the whole form is green only this particular field is
23:28
red how this is handled this is handled by our custom form validator class so
23:32
here since we are using a display inside the display form error function we are
23:38
attaching the field and the error value to our validation message store so this
23:43
field will contain the value for this username field that is why it is showing
23:47
error only at one particular field where it fit so I will use some other user
23:52
name which is available. Ankhish Sharma click on register so everything is good
23:57
registration successful message will be shown over here let us check our console
24:01
Now in the console you can see that there are few error messages since our validation
24:06
messages are failed. Finally when the validation is successful it says the registration is
24:10
successful. How this is working? So this is working from this particular logger. This
24:16
logger is logging the information that this registration is successful and it is shown
24:20
in our console over here. So that is how we can add a form to Blazor and then we can add
24:29
different kind of validation to it. Here we have seen how we can add invalid validation
24:34
such as required field, email, etc. We have also seen how we can add a custom client-side validation
24:40
and we have also seen how we can add a custom server-side validation
24:44
So finally, before I close, I want you guys to have a look at the resources
24:49
for this particular talk. So for this particular talk, I have created a GitHub repository
24:56
which is available at bit.ly blazer forms, And I have also written an article which explains you the step by step process of how to create
25:03
Blazor forms and how to do all different kinds of validation, which you can get at this particular
25:08
link, Bitly Blazor forms article. And you can also read other different kinds of blogs at my blog, ankishramablogs.com
25:16
And you can also connect with me via LinkedIn and Twitter. I will be happy to connect with you
25:20
Thank you all for joining. I hope you have enjoyed my talk. Over to you, Simon
#Windows & .NET
#Computer Education


