Blazor Server CRUD App Using Visual Studio Code
Tags: blazor, webapi, tutorial, vscode
Published: 2020-09-09 07:43:02

[**Blazor**](https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor) is a new Microsoft technology that allows developers to **write code for browsers in C# instead of JavaScript**. Blazor apps are composed of reusable web UI components implemented using C#, HTML, and CSS. Both client and server code is written in C#, allowing you to share code and libraries. Your C# code can easily call JavaScript APIs and libraries. You can continue to use the large ecosystem of JavaScript libraries that exist for client-side UI while writing your logic in C#.

**Blazor** is a web framework designed to run **client-side** in the browser on a [**WebAssembly**](https://webassembly.org/)-based .NET runtime (**Blazor WebAssembly**) or **server-side** in [**ASP.NET Core**](https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-3.1) (**Blazor Server**). Regardless of the hosting model, the app and component models are the same.

In this article, we will build a simple Employee Management system using Blazor **server-side** hosting model, which will allow us to perform CRUD operations. For this, we will be creating a **Blazor Server** web project, a **.Net Core Web API** project for managing the backend, and a **.Net Core Class Library** project for the model. 

For the development environment, We will be using [**Visual Studio Code**](https://code.visualstudio.com/).

The source code of the application that we will be building is available in my git repository [here](https://github.com/rineshpk/BlazorServerCRUD).

##Setup Development Environment
####Prerequisites

* [Visual Studio Code](https://code.visualstudio.com/)
* [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1)
* [SQL Server Express](https://go.microsoft.com/fwlink/?LinkID=866658)

####Install the required extensions in vscode

![vscode extensions](https://dev-to-uploads.s3.amazonaws.com/i/8qsg7se8zix7c58smsbr.PNG)

**C#** extension is required for debugging and IntelliSense support for C# code  
**C# Extensions** help us to create new classes, enums, and interfaces. It also provides a possible quick fix on `Ctrl+.`(Control + Period)
I have also installed some useful extensions like **Blazor Snippets**, **Razor+**, etc. to support the development workflow. There are a lot of extensions available at [Extension Marketplace](https://code.visualstudio.com/docs/editor/extension-gallery) 

I am using Visual Studio Code version 1.48.0 for this demo.
 
Let's create a folder named 'BlazorServerCRUD' at your preferred location. We will be using this as the root directory for our projects. 

Now we are all set to start our development.

##Create Blazor Server Web Application

Let’s create a Blazor Server project. In vscode, open a new integrated terminal window.The default terminal is a powershell and the location will be the default user directory. Use `cd` command and navigate to the directory we have created earlier.

![set directory](https://dev-to-uploads.s3.amazonaws.com/i/o4tlgwkai5i0wiazwpz8.PNG)
 
We can use the [**.NET Core CLI**](https://docs.microsoft.com/en-us/dotnet/core/tools/) command `dotnet new` for creating our project. We can create a new Blazor Server project using `blazorserver` template. [Here](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new) you can see a complete list of project templates that can be used with `dotnet new` command.
```c++
dotnet new blazorserver -o 'BlazorServerCRUD.Web'
```
![create new blazor server project](https://dev-to-uploads.s3.amazonaws.com/i/fbunt94rsejcs1vtcbt9.PNG)

A new blazor server web project is created. Now we need to open the project folder in vscode. In vscode explorer click *Open Folder* and select project directory.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3ztxw2fd6x6tmb51qs4p.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1iu78qiat9or147zscer.PNG)

In the vscode Explorer, we can see our newly created project and it should look like this,

![blazor project](https://dev-to-uploads.s3.amazonaws.com/i/q514umeqanf9pgjzhfoc.PNG)

Blazor project template contains some default files, if we run our application right away it will be launched as a Hello World! application.  For launching our application from vscode, we need to configure the vscode specific launch configuration. `launch.json` file is used to configure the debugger in vscode. 

vscode generates a `launch.json` file with almost all of the required information. Go to *Run* tab and click on *create a lauch.json file*, it will ask for the environment, select `.Net Core` (Do not select *Blazor WebAssembly Debug* as our application is Balzor Server app) as shown below,

![create launch json](https://dev-to-uploads.s3.amazonaws.com/i/bpgzwascw24253iy2aun.PNG) 

It will create `launch.json` file and it should look like this,

![launch json](https://dev-to-uploads.s3.amazonaws.com/i/xn1qjg9vv5ynu0mv8c12.PNG)

Click on *Add Configuration* button, a list of configurations will popup, select *.NET: Launch a local NET Core Web App* 

![launch config selection](https://dev-to-uploads.s3.amazonaws.com/i/16deb64k58224utn9qov.PNG)

This will add the required debug configuration, change`<target-framework>` to `netcoreapp3.1`, and `<project-name.dll>` to `BlazorServerCRUD.Web.dll` in the configuration file. Now launch file should look like this,

![launch config](https://dev-to-uploads.s3.amazonaws.com/i/z2l8p4zguwgwfnz2rb9g.PNG)

Our debug configuration is now complete. Ok, let's run our application by clicking *Run>Start Debugging* or by hitting *F5*

An error message will popup *Could not find the task 'build'* with an option to *Configure Task*. This is because we need to build our application before launch and in our `launch.json` *build* is specified as a *preLaunchTask*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qnh776s9bukl82tnwtwv.PNG)

Click on *Configure Task*, and select *Create task.json from the template* and select *.NET Core* template.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4vlp8hffa285o4wqafmw.PNG)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2u2t2oshiuzaeckqes57.PNG)

This will add a `task.json` file,

![task json](https://dev-to-uploads.s3.amazonaws.com/i/jnz8b5x59ptu6yrjze6i.PNG)
 
Now we are all set to build, debug, and launch our Blazor application. Hit F5, the app will be launched in the browser,

![blazor hello world launched](https://dev-to-uploads.s3.amazonaws.com/i/dltiwyrfcwon99g1h5f3.PNG)

We have successfully launched our Blazor Server App from vs code. Next, we need to create a model class. Here I'm going to create a model class in a separate .Net standard class library project 

##Create .Net Core Class Library Project 

We are going to create a new project, but the folder opened in vscode is the root of our web project. Now we need to manage multiple projects using one window. vscode has the concept of a 'workspace' which lets you add several 'root' folders to vscode in the same window.

So, lets set up our workspace in vscode. First, open the parent folder,

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9pid4ajeb2j8ul6shhw2.PNG)

Then save the opened folder as the workspace using *Save Workspace As* option in vscode.

![vscode workspace](https://dev-to-uploads.s3.amazonaws.com/i/nj21v4m4gj1op2t1a1c0.PNG)

Our workspace is ready. Let's create a class library project. For creating a .net core class library project, run the below command in a new terminal window,
```C++
dotnet new classlib -o BlazorServerCRUD.Models
```
Make sure to run the command from the workspace directory - BlazorServerCRUD

![class lib added](https://dev-to-uploads.s3.amazonaws.com/i/k23b7frkt4bwppv9yviz.PNG)

The new Class Library project will be added with the name *BlazorServerCRUD.Models* and the vscode Explorer should look like this,

![explorer with two projects](https://dev-to-uploads.s3.amazonaws.com/i/pri8uq4s3pb3tj4rz6ay.PNG)

Now, we have two projects in our vscode workspace and we need to add the library project reference to our web project. That means we may need to build both the projects while debugging our application. How do we do that? One option is to build class library project by using `dotnet build` command every time. To make it handier, we can add a solution(.sln) file and add both projects to that solution. Then both projects will be built at the time of debugging.

Let's see how we can achieve this in vscode. Open a new terminal and run `dotnet new sln` command to create a solution file
```c++
dotnet new sln -n BlazorServerCRUD
```
A new solution file will be created with the name 'BlazorServerCRUD'. Let's add our projects to this sln using `dotnet sln add` command.

```c#
dotnet sln add BlazorServerCRUD.Web/BlazorServerCRUD.Web.csproj
dotnet sln add BlazorServerCRUD.Models/BlazorServerCRUD.Models.csproj
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/iv9c9k9xzg0znv1c40zf.PNG)

For launching the application, vscode will look for `launch.json` and `task.json` in the root directory. As we changed our root directory from BlazorServerCRUD.Web to BlazorServerCRUD, we have to move these configuration files also. Alternatively, we can add new launch configuration files for the current root directory. Note that 'program' and 'cwd' location in our new `launch.json` is now changed to:
![program](https://dev-to-uploads.s3.amazonaws.com/i/9sl89v5zgyv91n5m12js.PNG)
![cwd](https://dev-to-uploads.s3.amazonaws.com/i/7676px9v9r1qur5hjcxp.PNG)
![new launch configuration](https://dev-to-uploads.s3.amazonaws.com/i/gl7t4k5h77ax4sqqir0t.PNG)

Now we have completed our launch configuration changes as per the vscode workspace changes. Run the application and make sure everything is setup correctly.

Let’s create an Employee Model class with some properties. You can do this by right click on `BlazorServerCRUD.Models` and select  'New Class'. 

![new class](https://dev-to-uploads.s3.amazonaws.com/i/jsldidd4t8j3kucmu8se.PNG)
Note: You will see this 'New Class' context menu option only if you installed **C# Extensions** extension in vscode
![C# Extensions](https://dev-to-uploads.s3.amazonaws.com/i/aeu0zg28c2zmo6bjlgv6.PNG)

The Employee Model class should look like this.

![employee class](https://dev-to-uploads.s3.amazonaws.com/i/bzz9ezl9braq83nkq4rh.PNG)

For the `Gender` property, I have created a separate `enum` class as shown below.

![gender enum](https://dev-to-uploads.s3.amazonaws.com/i/9kos9393olqd2paypaod.PNG)

For `Department` property, I have created another `class` with DepartmentId and DepartmentName properties.

![department class](https://dev-to-uploads.s3.amazonaws.com/i/tuvay552n5721n2fsode.PNG)

Now, let’s add BlazorServerCRUD.Models as a reference to BlazorServerCRUD.Web. We can use `dotnet add reference` command to add a project reference. Run this command from web project folder, i.e., use `cd BlazorServerCRUD.Web` and run below command.

```c#
dotnet add reference ../BlazorServerCRUD.Models/BlazorServerCRUD.Models.csproj
```

![dotnet add reference](https://dev-to-uploads.s3.amazonaws.com/i/4lw3m2kpdat7pclcytfs.PNG)

Now we have created our model class library project and referenced it to our blazor web application. 
Our next step is to create an API project to manage employee data.

##Create ASP.Net Core Web API

For managing the data-access we will be adding a REST API project as a third project. Let’s add the api project using `dotnet new` command and add to our solution as shown below. `--nohttps` is used because we don't want https bindings for dev environment. 

![api added](https://dev-to-uploads.s3.amazonaws.com/i/w39tsjru0i7qan2i0il4.PNG)

####Run Multiple Projects in Visual Studio Code

Our blazor application is going to use the newly created API for backend data access. i.e., These two projects need to be launched simultaneously. To do this, we need to add one more configuration in our `launch.json` file. Open `launch.json` file in `.vscode` directory and click on *Add Configuration* button at the bottom right corner. Select *.NET: Launch a local NET Core Web App*. It will add one more ".NET Core Launch (web)" configuration. Change the `name` to ".NET Core Launch (api)" for identifying the launch settings. Set `program` property of newly added configuration to pointing to API application dll.

![program](https://dev-to-uploads.s3.amazonaws.com/i/ek3bdtcgacs7jtsggyfx.PNG)

Now we have two debug configurations and this is all fine but doesn’t give us a way to run both of our projects. Let’s tweak the `env` property to set the `ASPNETCORE_URLS` which will control the application launch URL. Our Web API URL is set to `http://localhost:5000` and Web Application URL is now set to `http://localhost:5001` 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ssonh9mp2wvese8vrdzt.png)

The following is the full configuration in my `launch.json`
```json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (Api)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/BlazorServerCRUD.Api/bin/Debug/netcoreapp3.1/BlazorServerCRUD.Api.dll",
            "args": [],
            "cwd": "${workspaceFolder}/BlazorServerCRUD.Api",
            "stopAtEntry": false,
            "serverReadyAction": {
                "action": "openExternally",
                "pattern": "\\bNow listening on:\\s+(https?://\\S+)",
                "uriFormat": "%s/api/employee"
            },
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development",
                "ASPNETCORE_URLS": "http://localhost:5000"
            },
        },
        {
            "name": ".NET Core Launch (web)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/BlazorServerCRUD.Web/bin/Debug/netcoreapp3.1/BlazorServerCRUD.Web.dll",
            "args": [],
            "cwd": "${workspaceFolder}/BlazorServerCRUD.Web",
            "stopAtEntry": false,
            "serverReadyAction": {
                "action": "openExternally",
                "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
            },
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development",
                "ASPNETCORE_URLS": "http://localhost:5001"
                
            },
            "sourceFileMap": {
                "/Views": "${workspaceFolder}/BlazorServerCRUD.Web/Views"
            }
        }

    ]
}
```
Now that all our configurations are good to go.

Go to the vscode Run tab, there you can see both of our launch configurations listed. If you select the 'API' one and hit the green play button it will start the API. With the API running you can then select the 'Web' configuration and hit the green play button and you will have both of your applications running in debug mode.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i2g8uh8lsxjvnzxrkflu.PNG)

####Add Entity Framwork Core
Now we are going to add database support to our project. To do this, For data access, we are using [Entity Framework Core](https://docs.microsoft.com/en-us/ef/). To add EF Core to our project, we will need to install `Microsoft.EntityFrameworkCore.SqlServer` and `Microsoft.EntityFrameworkCore.Tools` NuGet packages. Let's do this by using the `dotnet add package` command. These packages need to be installed in the API project. Open new terminal window and navigate to BlazorServerCRUD.Api directory and run the commands.

![ef core](https://dev-to-uploads.s3.amazonaws.com/i/rbc3scryl9r6pp6yzu5x.PNG)
![ef core tools](https://dev-to-uploads.s3.amazonaws.com/i/j657pazuwjy6mgzeur2q.PNG)

We also, need to add our model class library project reference to the API project. 

![model reference](https://dev-to-uploads.s3.amazonaws.com/i/5sax5c9xbsvgrndqneak.PNG)

Now we have added the required packages and references to our API project. Let's verify that in the API project file.

![API project file](https://dev-to-uploads.s3.amazonaws.com/i/ko3sm89mt7poxd3l6doa.PNG)

In this demo, I'm using EF Core Code First approach for data access. To get started with this, Let’s add the connection string to the `appsettings.json` file of `BlazorServerCRUD.Api` project. The connection string added is shown below. Here I'm using [SQL Server Express LocalDB](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/sql-server-express-localdb?view=sql-server-ver15) for the database.
```c#
Server=(localdb)\\mssqllocaldb;Database=DBEmployees;Trusted_Connection=True;MultipleActiveResultsets=true
```
![Connection String](https://dev-to-uploads.s3.amazonaws.com/i/ikusmznt229hy30qu48d.PNG)

Let’s add a new folder called `Models` to `BlazorServerCRUD.Api` project and add a new class called `AppDbContext.cs`.

![AppDbContext](https://dev-to-uploads.s3.amazonaws.com/i/num6eesiv30p2hoj3mbk.PNG)

Modify `AppDbContext` class to derive from `DbContext`. For this, we need to import the namespace `Microsoft.EntityFrameworkCore`. With the help of *C# Extensions* vscode will show a quick fix to import this namespace.

![quick fix](https://dev-to-uploads.s3.amazonaws.com/i/skka9fskrfxmqqhed1hk.PNG)

For the `DbContext` class to be able to do any useful work it needs an instance of `DbContextOptions` class. The `DbContextOptions` instance carries configuration information such as the connection string and the database provider to use. We are passing the instance of `DbContextOptions` class to `base` `DbContext` class. The updated class should look like this.

![The updated class](https://dev-to-uploads.s3.amazonaws.com/i/k1bn6ippvcm2ys8ho67c.PNG)

Now we will create a `DbSet` property for each of the entities created in our application. At the moment we have `Department` and `Employee` classes that represent the corresponding database table. We will use these `DbSet` properties to query and save instances of Employee and Department classes. The updated code is as shown below.

![dbset](https://dev-to-uploads.s3.amazonaws.com/i/q5wkkyltowtmqkz6vqj7.PNG)

Let’s add some seed data for the employees and the department. We can do that by overriding `OnModelCreating` class. Before that, let's change the `Department` property in `Employee` class to `int DepartmentID` for simplicity. 

![DepartmentID](https://dev-to-uploads.s3.amazonaws.com/i/86il6grkmka8yftgcuvw.PNG)

![seed data](https://dev-to-uploads.s3.amazonaws.com/i/0lt9k9ex3zofxt49mn3c.PNG)

The next step is to configure the SQL Server in Startup class, under `ConfigureServices` method as shown below.

![startup](https://dev-to-uploads.s3.amazonaws.com/i/5g8i8813rpx0ktmf6x9r.PNG)

The last step is to add database migration. To do that, we need to install [**.Net Core EF Tools.**]
(https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet) Use the following command to install ef tools globally.
```c#
dotnet tool install --global dotnet-ef
```
![dotnet-ef](https://dev-to-uploads.s3.amazonaws.com/i/t36gxxm711qyolqfnaml.PNG)

Now let's add database migration using `dotnet ef migrations add` command.

![migrations](https://dev-to-uploads.s3.amazonaws.com/i/ig6spcrv5sycl2xdyzbi.PNG)

Once migration is successful, a migrations folder will be added to API project.

![migraton folder](https://dev-to-uploads.s3.amazonaws.com/i/kyzsm55ozycijtm78b93.PNG)

The next step is to apply the created migration. To do that we will run `dotnet ef database update` command. 

![database update](https://dev-to-uploads.s3.amazonaws.com/i/2dog02g653vadxwxxk9b.PNG)

Once this is successfully completed, we will have our tables with our seed data created in EmployeeDB database. You can see the DB creation logs while applying the migration as in the below image.

![db logs](https://dev-to-uploads.s3.amazonaws.com/i/423ni6eexz306wcu3b9p.PNG)

Now the database is set up with our seed data we can start to implement the CRUD operations. We are going to use the repository pattern to implement the logic required to access the data source.

Let's create an interface `IEmployeeRepository` which defines all the CRUD operations to be performed against the employee object.
For this, we have to import `BlazorServerCRUD.Models` to this interface. Let's do this by using the *quick fix*

![quick](https://dev-to-uploads.s3.amazonaws.com/i/2uao6844qusplw1dv7cm.PNG)

I have added all the methods to perform CRUD operations in `IEmployeeRepository` interface.

![IEmployeeRepository](https://dev-to-uploads.s3.amazonaws.com/i/8xlxi447hg8wkbiadz53.PNG)

Next step is to create `EmployeeRepository` class and implement `IEmployeeRepository` interface.

![implement ](https://dev-to-uploads.s3.amazonaws.com/i/tajw1w17axbut9eti4rx.PNG)

This `EmployeeRepository` class will need the `AppDbContext` class to communicate with the SQL database. We can do that by injecting an instance of AppDbContext class through the constructor.

![injecting ](https://dev-to-uploads.s3.amazonaws.com/i/q6p6hz5if4g02emq2bc1.PNG)


We have the dependency of `AppDbContext` injected in `EmployeeRepository` class. Now let’s add the actual implementations to all CRUD methods as shown below. 

![implementations](https://dev-to-uploads.s3.amazonaws.com/i/d5ona01xl7vr1ia7w2h7.PNG)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yamv0fvtb2y3h5736mkc.PNG)

Same way, we have to create an interface class called IDepartmentRepository and the implementation class `DepartmentRepository` for the Department entity as shown below.

![Department](https://dev-to-uploads.s3.amazonaws.com/i/t9yzegumlp85o5ae0hrj.PNG)

And, we need to register repository implementation with the interface in Startup.cs class.

![register repository](https://dev-to-uploads.s3.amazonaws.com/i/97dgh2f5328cc5wu00lk.PNG)

Now we have our repository classes ready. Let's build our REST API to access the employee data. We first need to create a controller class. I have created an EmployeesController class which derives from ControllerBase class. To do this, we can use [aspnet-codegenerator (Scaffolding)](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/tools/dotnet-aspnet-codegenerator?view=aspnetcore-3.1). This tool runs the ASP.NET Core scaffolding engine for avilable generators like controller. Let's install **dotnet aspnet-codegenerator** by running the below command.
```c#
dotnet tool install -global dotnet-aspnet-codegenerator
```
![dotnet-aspnet-codegenerator](https://dev-to-uploads.s3.amazonaws.com/i/zm2la5avcvtnp0erim1a.PNG)

We also need to add `Microsoft.VisualStudio.Web.CodeGeneration.Design` for scaffolding our controller. Let's add this package using the following command
```c#
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
```
![VisualStudio CodeGeneration](https://dev-to-uploads.s3.amazonaws.com/i/qk4wqdnllrrerewmn1o5.PNG)

We are all set to create our first controller using **dotnet aspnet-codegenerator**. Run the below command to generate our `EmployeeController` 
```c#
dotnet aspnet-codegenerator controller -name EmployeeController -api -outDir Controllers
```
![EmployeeController](https://dev-to-uploads.s3.amazonaws.com/i/8u5glurrpq74ix3onmv9.PNG)

Now, In order to retrieve Employees data from the database, we will need access to EmployeeRepository. I have updated the Employees controller class to inject an IEmployeeRepository class through a constructor as shown below.

![IEmployeeRepository ](https://dev-to-uploads.s3.amazonaws.com/i/xbp08g1gkrxzydelqeir.PNG)

Let’s add a `HttpGet` method `GetEmployees` to retrieve the list of all employees. It will return an Http status code of `200 OK` as a response by using the inbuilt `OK` method available in `ControllerBase` base class.

![GetEmployees](https://dev-to-uploads.s3.amazonaws.com/i/73qlcczswkuc2se6a2zw.PNG)

Similarly, let's add other required methods in this `EmployeeController`. Another `HttpGet` method with the `id` parameter for fetching employee data of a specific employee by id, a `HttpPost` method for saving, a `HttpPut` method for updating, and an `HttpDelete` for deleting employee data. 

![controller](https://dev-to-uploads.s3.amazonaws.com/i/q6ea5lwu9sbzcgaw87d8.PNG)

Let’s add a `uriFormat` property for `serverReadyAction` in `launch.json` configuration settings for the API to call our employee controller when we launch our application as shown below.

![uriFormat](https://dev-to-uploads.s3.amazonaws.com/i/i8evfumk2ftzssvze25a.PNG)

Now we can test our API by launching the application. Go to *Run* and select *.NET Core Launch (Api)* and hit the play button.

![Run](https://dev-to-uploads.s3.amazonaws.com/i/vqord9zpve8bf8v9qdco.PNG)

Our API will be launched in the browser with `api/employees` URL by default which in turn calls the `GetEmployees` method to return the list of employees.

![employees](https://dev-to-uploads.s3.amazonaws.com/i/hct29ch7y1ys1lwfn6gk.PNG)

Now we have our API ready to supply some data. Before implementing all CRUD operations, let's go back to our Blazor web project and see how we can consume this API to display the employee list.  

##Customize Blazor Server Web Application

In our blazor project, there are some default files included as part of the project template. Let’s delete the unnecessary files which we don’t need for this project. I have highlighted the files to be deleted below. 

![remove files](https://dev-to-uploads.s3.amazonaws.com/i/38akvkrqqyvdeloq7txh.PNG)

Also, remove the deleted files references from Startup.cs class.

![start up](https://dev-to-uploads.s3.amazonaws.com/i/wdgusg5bnoldaw34i2hm.PNG)

And, remove the unwanted menu from NavMenu.razor file. Highlighted below. 

![remove menu](https://dev-to-uploads.s3.amazonaws.com/i/zoionnxibishdqdmspmc.PNG)

As we got rid of all unwanted files, let’s launch our application and see what we have got so far. The page will show nothing as there is nothing linked to home/root address. 

![app launched](https://dev-to-uploads.s3.amazonaws.com/i/du8d12ru79uxysxjzgy6.PNG)

Let’s modify the logic to show the employee list. To do this, add a razor component called `EmployeeList.razor` in `Pages` folder. You can use the `dotnet new razorcomponent` command to add a new razor component.

![razorcomponent](https://dev-to-uploads.s3.amazonaws.com/i/b4u44ostjg0cvbvdjkc0.PNG)

EmployeeList.razor component will look like this.

![EmployeeList.razor](https://dev-to-uploads.s3.amazonaws.com/i/uekuw3yhsozd8aiuzzws.PNG)

Now to link `EmployeeList.razor` component to the root address, add `@page` directive as shown below.

![page directive](https://dev-to-uploads.s3.amazonaws.com/i/lu92wwd4n3g79h2xhvv2.PNG)

Now let’s run the project again. As you can see below. EmployeeList component is appearing at the root URL.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wn5fkvw94fa5beja2y7u.PNG)

Now we have created our first razor component to view the employee list. 
Next, we need to call our REST API created in BlazorServerCRUD.Api project from our BlazorServerCRUD.Web Blazor application. 
We will create a separate service that will call the REST API. To do that I have added a new folder called Services to BlazorServerCRUD.Web project. I added a new Interface file called IEmployeeService with GetEmployees as an interface method as shown below.

![IEmployeeService](https://dev-to-uploads.s3.amazonaws.com/i/itgb28zgure2z58k9jjs.PNG)

I have added another implementation class called `EmployeeService` that implements `IEmployeeService` interface. To call our API from EmployeeService, we need an `HttpClient`. Let's inject the HttpClient instance in EmployeeService.

![HttpClient](https://dev-to-uploads.s3.amazonaws.com/i/r38tml5ndto60hoo4o7a.PNG)

Next, we will have to register `Httpclient` service to the ASP.Net Core dependency injection container by using `AddHttpClient` method and map `IEmployeeService` interface to the EmployeeService class. Also, add the base address of our API.

![AddHttpClient](https://dev-to-uploads.s3.amazonaws.com/i/i3tgc8j3s5jgt461m1as.PNG)

Next, we have to install `Microsoft.AspNetCore.Blazor.HttpClient` Nuget Package in our BlazorServerCRUD.Web project. Currently, it is a prerelease. Lets add the package by running below command,
```c#
dotnet add package Microsoft.AspNetCore.Blazor.HttpClient --version 3.2.0-preview3.20168.3
```
![Blazor HttpClien](https://dev-to-uploads.s3.amazonaws.com/i/ewscs0ww7a8qe6d2vgun.PNG)

Let’s now use `httpClient` instance in our `EmployeeServices` class to call REST API through `GetEmployees` method. I have used `GetJsonAsync` method which returns an array of Employee. This is an extension method for HttpClient. Include `Microsoft.AspNetCore.Components` namespace to make this method to appear. The method also requires the path to access the resource. The given path `/api/employee` is appended to the `BaseAddress` to return the result.

![GetJsonAsync](https://dev-to-uploads.s3.amazonaws.com/i/in86djsxicget2b4a7d7.PNG)

Now, let's modify our `EmployeeList` razor component to display the employee data accessed through `EmployeeService`. First, we need to inject `IEmployeeService` to our `EmployeeList` blazor component.

![EmployeeList](https://dev-to-uploads.s3.amazonaws.com/i/06vfvtk0dyszun4193o3.PNG)

This injected `EmployeeService` instance is then used in [ASP.NET Core Blazor lifecycle](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-3.1) method `OnInitializedAsync` to fetch the list of Employees. This returned data is assigned to `employees` property.

![OnInitializedAsync](https://dev-to-uploads.s3.amazonaws.com/i/ymia3n7sf77w3chibvho.PNG)

`EmployeeList.razor` page uses that `employees` property to display the data on the screen. Let's add some HTML to our razor component to display the data as shown below.

![HTML](https://dev-to-uploads.s3.amazonaws.com/i/j8g3ynbfsg2ro97rlzir.PNG)

We are all set to display the data we fetch from the API in our blazor application. Go to *Run* and first start the API and then the web application. Now you can see the employee list component now displays data from the database using REST API.

![Launched](https://dev-to-uploads.s3.amazonaws.com/i/cehgyn79icwyimp0hyxb.PNG)

We have now displayed employee data from the `Employee` table. You can see, here the department is shown as Department Id. To display the department name, we have to fetch data from the `Department` table. To do this, Let's add a [navigation property](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/navigation-property) for `Department` in the `Employee` entity class.

![nav prperty](https://dev-to-uploads.s3.amazonaws.com/i/ezx79hobvxnzo29m34kb.PNG)

Then we have to update `GetEmployees` and `GetEmployee` methods to include `Departments` table data by chaining `Include` method as shown below.

![Include](https://dev-to-uploads.s3.amazonaws.com/i/3hb1cshhxszhmkzf10je.PNG)

Next, We need to update the `EmployeeList.razor` Blazor component to display the department name instead of the department id. 

![EmployeeList](https://dev-to-uploads.s3.amazonaws.com/i/d8034pz34d5ybqdpzcut.PNG)

Let's run the application and blazor component will show the department name instead of department Id.

![department name](https://dev-to-uploads.s3.amazonaws.com/i/o5m1kkfhx5tic7s3caye.PNG)

Our next step is to get details of a specific employee. For this, let's add a new razor component `EmployeeDetails.razor` to display the details of a specific employee. 

```c#
dotnet new razorcomponent -n EmployeeDetails -o Pages
```

![EmployeeDetails.razor](https://dev-to-uploads.s3.amazonaws.com/i/493kziqi15dvtdtsq7of.PNG)

We will be navigating to this page from our `EmpoloyeeList` page. To do this, we will have to provide a route parameter by using `@page` directive. Here `{id}` is the route parameter that will represent the employee Id.

To access `{id}` route parameter, we have to create a property in our `EmployeeDetails.razor` and decorate it with `[Parameter]` attribute. With this change, the `id` route parameter will be directly mapped to `Id` property.

![route parameter](https://dev-to-uploads.s3.amazonaws.com/i/1clcevnjpft7q9vvwy6n.PNG)

Now, let's add a method `GetEmployee` to access the details of the employee in `IEmployeeService` interface and implement it in the `EmployeeServices` as shown below,

![IEmployeeService](https://dev-to-uploads.s3.amazonaws.com/i/zje16ss1k5adjgx0my30.PNG)
![EmployeeServices](https://dev-to-uploads.s3.amazonaws.com/i/kxiw096m3rysklzygt8b.PNG)

*Note:* You can import required namespace to components using `_import.razor` as shown below,

![_import.razor](https://dev-to-uploads.s3.amazonaws.com/i/z5uue5nmq5qus8kozl9n.PNG)

To call our `GetEmployee` method from the employee details page, let's inject the `IEmployeeService` in the component. To store the result from this method we also need to create an `Employee` property. With these changes, our `EmployeeDetails.razor` component should look like this.

![EmployeeDetails.razor](https://dev-to-uploads.s3.amazonaws.com/i/aqbn1maiz872qd1vos35.PNG)

Next, we can use [ASP.NET Core Blazor lifecycle](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-3.1) method `OnInitializedAsync` to retrieve employee data by id.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0nk7u500bw9bwot3tnuw.PNG)

Let's add the HTML in `EmployeeDetails.razor` component to display employee details using the `employee` property. Also added the buttons to perform 'Edit', 'Delete', and 'Back' operations which we are going to implement next. To avoid `NullReferenceException` error add an `If` clause to check if the `Employee` property is initialized before using it.

![HTML in EmployeeDetails.razor](https://dev-to-uploads.s3.amazonaws.com/i/99p5cnxrzwrqvbv428dw.PNG)

For accessing the above Employee details page, let's add a link in our Employee list page.

![Employee list](https://dev-to-uploads.s3.amazonaws.com/i/ksyxawobswrd6chvpixf.PNG)

With all these changes saved, let's run our application. In the employee list page, click on the employee name. We will be redirected to our employee details page and it should look like this

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ejxozzrn6csoh1onrhyh.PNG)

Now, we have displayed details of a specific employee by using the employee id. Next, we are going to implement the actual CRUD operations. For this, we have to add the necessary methods in our `IEmployeeService` interface,

![IEmployeeService](https://dev-to-uploads.s3.amazonaws.com/i/1lmsgzzi2q8ixbfo6tq2.PNG)

And, implement these methods in `EmployeeService` class.

![EmployeeService](https://dev-to-uploads.s3.amazonaws.com/i/813rn9l898ri0imrrgpl.PNG)

For understanding [ASP.NET Core Blazor event handling](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/event-handling?view=aspnetcore-3.1), let's implement the **Delete** operation first.

For this, add a new method `DeleteEmployee()` in `EmployeeDetails.razor` component. 

![DeleteEmployee](https://dev-to-uploads.s3.amazonaws.com/i/qq0zv1h5vvhvfd686ioe.PNG)

And, call this method in `@onclick` event handler as shown below,

![onclick](https://dev-to-uploads.s3.amazonaws.com/i/caztimz58phs4hgppptr.PNG)

With these changes saved, we have implemented the **Delete** operation. Run the application, go to employee datils you want to delete, and click on the delete button. The employee data for this particular employee will be deleted from the database. Now you need to navigate to home manually to verify this. For handling URI redirection in ASP.NET Core, we can use [**NavigationManager Class**](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.navigationmanager?view=aspnetcore-3.1). Let's inject `NavigationManager` in `EmployeeDetails.razor` and modify the `Delete` method as shown below.

![Employee Details](https://dev-to-uploads.s3.amazonaws.com/i/0sx73765knrnzjn73qhw.PNG)
![delete](https://dev-to-uploads.s3.amazonaws.com/i/t3wavqehxrl50o3g68ka.PNG)

Now, on clicking the *Delete* button on the employee details page, you will be redirected to the home page. You can see the deleted employee is not listed on the homepage anymore.

![deleted](https://dev-to-uploads.s3.amazonaws.com/i/2iz55xu6n2tyta0mmtsg.PNG)

Now, let's implement **Create** and **Update** operations. For this, we will be using `CreateEmployee.razor` and `UpdateEmployee.razor` respectively. Before creating these two components, let's create a child component that can be shared by both create and update components. Here we will also learn how to **pass data from parent component to child component** using parameters.

Let's add a razor component `Form.razor` in the `Pages` folder.
```c#
dotnet new razorcomponent -n Form -o Pages
```
In this `Form.razor` component we will be using [**ASP.NET Core Blazor forms and validation**](https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-3.1). Forms and validation are supported in Blazor using data annotations.

In this `Form.razor`, add an [EditForm](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.forms.editform?view=aspnetcore-3.1) tag that takes in an `Employee` model and has a function call to submit. Inside the `EditForm` tag, we are going to add required blazor form controls and validations. 

In the `@code` section of `Form.razor`, declare the parameters using the `[Parameter]` attribute. These parameters are used for passing data between parent and child components. We have an `Employee` object, a string for holding the button text, and an `EventCallback` for the method to be called on submitting the form. Below is my `Form.razor` component.
>PS. Here the department select is hardcoded for simplicity, in real scenarios the department values should be fetched from the database.

```c#
<EditForm Model="@employee" OnValidSubmit="@OnValidSubmit">
    <DataAnnotationsValidator />
    <div class="form-group">
        <label>Employee Name :</label>
        <div>
            <InputText @bind-Value="@employee.EmployeeName" class="form-control col-sm-3" />
            <ValidationMessage For="@(() => employee.EmployeeName)" />
        </div>
    </div>
    <div class="form-group ">
        <div>
            <label>Gender :</label>
            <div>
                <InputSelect @bind-Value="@employee.Gender" class="form-control col-sm-3"> 
                   <option value="Select">--Select--</option>
                   <option value="Male">Male</option>
                   <option value="Female">Female</option>
                   <option value="Other">Other</option>
                </InputSelect>
                <ValidationMessage For="@(() => employee.Gender)" />
            </div>
        </div>
    </div>
    <div class="form-group ">
        <div>
            <label>DOB :</label>
            <div>
                <InputDate @bind-Value="@employee.DateOfBirth" class="form-control col-sm-3" />
                <ValidationMessage For="@(() => employee.DateOfBirth)" />
            </div>
        </div>
    </div>
    <div class="form-group ">
        <div>
            <label>Department :</label>
            <div>
                <select @bind="@employee.DepartmentID" class="form-control col-sm-3"> 
                   <option value=0>--Select--</option>
                   <option value=1>Admin</option>
                   <option value=2>HR</option>
                   <option value=3>Payroll</option>
                </select>
                <ValidationMessage For="@(() => employee.DepartmentID)" />
            </div>
        </div>
    </div>
    <button type="submit" class="btn btn-success">
        @ButtonText
    </button>
</EditForm>

@code {
    [Parameter]
    public Employee employee { get; set; }
    [Parameter]
    public string ButtonText { get; set; } = "Save";
    [Parameter]
    public EventCallback OnValidSubmit { get; set; }
}

```
Now, let’s start using our Forms component. Create a new razor component `CreateEmployee.razor`

```c#
dotnet new razorcomponent -n CreateEmployee -o Pages
```
For navigating to this create employee page, let's add a `@page` directive. Then, inject `IEmployeeService` for calling the `AddEmployee` method and inject `NavigationManger` for handling redirection from this component. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2j1lst4qy9dwd5q05xpw.PNG)

In this `CreateEmployee` component, add the `Form` component we have created earlier. To this `Form` component, we need to pass three parameters. 'ButtonText' string, 'employee' object, and 'OnValidSubmit' method. To do this, let's create an `Employee` object and a method in the `@code` section. With these changes, our `CreateEmployee.razor` should look like this,

![CreateEmployee](https://dev-to-uploads.s3.amazonaws.com/i/34m6t7n5dom4mh3x80ku.PNG)

Now, we will have to create a link to `CreateEmployee` from home page. To do this, let's modify the `EmployeeList` component and add a 'Create New' button. I have added an anchor tag with `href="createemployee"` as shown below,

![Create New](https://dev-to-uploads.s3.amazonaws.com/i/0xqok6gp817kesoz8fkd.PNG)

With all these changes saved, let's run our application. On the home page, you can see a 'Create New' button displayed. 

![home page](https://dev-to-uploads.s3.amazonaws.com/i/jj97x3cmsgsaghcmbktb.PNG)

By clicking on the 'Create New' button, you will be navigated to `CreateEmployee` component.

![CreateEmployee](https://dev-to-uploads.s3.amazonaws.com/i/d93q9s3n0pgxktktenoe.PNG)

You can see the create employee form with the button text as 'Create Employee'. Here you can save the employee details and you will be navigated to home. The newly created employee will be displayed in the employee grid.

![employee grid](https://dev-to-uploads.s3.amazonaws.com/i/vm7qhh71qec6bst94nuf.PNG)

Now, let's implement the **Update** operation. First, Create a new razor component `UpdateEmployee.razor`

```c#
dotnet new razorcomponent -n UpdateEmployee -o Pages
```
In this `UpdateEmployee` component, we can use the same `Form` component with a different button text. Add a `@page` directive with a route parameter. Here `{id}` is the route parameter that will represent the employee Id. Then, inject `IEmployeeService` for calling the `UpdateEmployee` method and inject `NavigationManger` for handling redirection from this component. 

![UpdateEmployee](https://dev-to-uploads.s3.amazonaws.com/i/pgnq4ahddd7dfx1ny4y2.PNG)

Same as we did in the `CreateEmployee`component, in `UpdateEmployee` component, add the `Form` component and we need to pass three parameters. 'ButtonText' string, 'employee' object, and 'OnValidSubmit' method. To do this, let's create an `Employee` object and a method in the `@code` section. In addition to this, to access the `{id}` route parameter, we have to create a property `Id` and decorate it with the `[Parameter]` attribute. Also, we need to fetch the details of the employee using this `Id` parameter. For this we can use a different [ASP.NET Core Blazor lifecycle](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle) method [OnParametersSetAsync](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.componentbase.onparameterssetasync?view=aspnetcore-3.1). With these changes, our `UpdateEmployee.razor` should look like this.

![UpdateEmployee](https://dev-to-uploads.s3.amazonaws.com/i/4ej5kcdlp7pzjfrmi87w.PNG)

Now, we are all set with our `UpdateEmployee` component. We will be navigating to this component form our `EmployeeDetails` component. In `EmployeeDetails.razor`, let's modify the 'Edit' button and add a link to `UpdateEmployee` with `@employee.EmployeeID` as routing parameter.

![EmployeeDetails](https://dev-to-uploads.s3.amazonaws.com/i/s7r81lxziwrrtnys7dq6.PNG)

With all these changes saved, let's run our application. From the employee list component, click on the employee name. It will navigate to employee details. 

![employee details](https://dev-to-uploads.s3.amazonaws.com/i/ljgt77sidiuv8mieovqk.PNG)

Click on the 'Edit' button, our update employee form will be loaded with all the employee details, and the button text will be displayed as 'Update  Employee'. 

![update employee](https://dev-to-uploads.s3.amazonaws.com/i/3xc8539nfexhllknyrun.PNG)

Modify any field and click on the 'Update Employee' button, you will be navigated to the employee list and there you can see the employee details updated.

![Updated](https://dev-to-uploads.s3.amazonaws.com/i/ommem77x2evm7welrg5w.PNG)

###Summary

In this article, we covered an introduction to ASP .Net Core Blazor Server Application and How to perform basic CRUD operations with blazor application. We have also learned how to set up the ASP.Net Core development environment in Visual Studio Code as well as Working with multiple projects in the Visual Studio Code. We built an ASP.NET Core 3.1 WebAPI with Entity Framework Core for managing the backend data. You can find the [complete source code here](https://github.com/rineshpk/BlazorServerCRUD).