First CRUD Application in ASP.NET Core MVC

First CRUD Application in ASP.NET Core MVC

You are now in a position to learn CRUD operations. For this I will create a small ‘Employee’ form which can be filled and submitted. On submission, the employee information will be stored. Later on I will also make Read, Update & Delete operations.

This form has 5 fields:

  • Name: Contains employee name.
  • Age: Contains employee age.
  • Salary: Contains employee salary.
  • Department: For employee department
  • Sex: For employee sex.
Create Employee Model

First create a class inside the ‘Models’ folder and name is ‘Employee.cs’. Add the below code to this class:

using System;

namespace FirstApp.Models
{
    public class Employee
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public decimal Salary { get; set; }
        public string Department { get; set; }
        public Char Sex { get; set; }
    }
}

Note: I have taken Char for Sex property to hold either ‘M’ for male or ‘F’ for female.

Now I have to store the Employee data somewhere in my application. For this I will create a static class. So create a new class inside the ‘Models’ folder and name it ‘Repository.cs’.

The ‘Repository.cs’ class is given below:

using System.Collections.Generic;

namespace FirstApp.Models
{
    public static class Repository
    {
        private static List<Employee> allEmpoyees = new List<Employee>();
        public static IEnumerable<Employee> AllEmpoyees
        {
            get { return allEmpoyees; }
        }
        public static void Create(Employee employee)
        {
            allEmpoyees.Add(employee);
        }
    }
}

In this static class there is a private field ‘allEmployees’ which is of type List. This field will contain all employees which are submitted from the form.

The public property ‘AllEmployees’ of type IEnumerable will return ‘allEmployees’ variable.

There is also ‘Create’ function that will simply add the employee, which is passed to it’s parameter, to the ‘allEmployees’ list.

Create Employee Form View

Now I will create the form, for this create ‘Create.cshtml’ inside Views ➤ Employee folder.

Add model of type Employee to it on top – @model Employee.

Also create a form on it where users can fill and submit details.

The whole code of the Create View is given below:

@model Employee
@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>
<form method="post">
    <p>
        <label asp-for="Name">Your Name:</label>
        <input asp-for="Name" />
    </p>
    <p>
        <label asp-for="Age">Your Age:</label>
        <input asp-for="Age" />
    </p>
    <p>
        <label asp-for="Salary">Your Salary:</label>
        <input asp-for="Salary" />
    </p>
    <p>
        <label asp-for="Department">Your Department:</label>
        <select asp-for="Department">
            <option value="Development">Development</option>
            <option value="HR">HR</option>
            <option value="Research">Research</option>
        </select>
    </p>
    <p>
        <label asp-for="Sex">Your Sex:</label>
        <input type="radio" asp-for="Sex" value="M" />Male
        <input type="radio" asp-for="Sex" value="F" />Female
    </p>
    <p><button type="submit">Submit</button></p>
</form>

When you see the form’s code you will notice asp-for attributes applied on the HTML tags. The asp-for is a tag helper attribute which binds the HTML tags (labels, inputs, select, etc) with the model properties.

The asp-for attribute on the label element sets the value of it’s ‘for’ attribute. The asp-for attribute
on the input & select elements set its ‘id’ and ‘name’ elements.

So for the asp-for tag applied on the ‘Name’ section of the form (given below):

<label asp-for="Name">Your Name:</label>
<input asp-for="Name" />

The HTML formed on the browser will be (given below):

<p>
    <label for="Name">Your Name:</label>
    <input type="text" id="Name" name="Name" value="">
</p>

In the same way the asp-for tag helper is applied to the select tag.

<select asp-for="Department">
    <option value="Development">Development</option>
    <option value="HR">HR</option>
    <option value="Research">Research</option>
</select>

For creating Radio buttons I have created 2 input type=”radio” tags and have bind both of them to the Sex property by using asp-for tag helpers. You may also note one has the value ‘M’ (for male) and other ‘F’ (for female).

<input type="radio" asp-for="Sex" value="M" />Male
<input type="radio" asp-for="Sex" value="F" />Female

There is also a button of type submit just before the ending form’s tag. When this button is clicked the form is submitted.

Next I will create the Controller.

Create Employee Controller

Create a new Controller inside the Controllers folder and name it ‘EmployeeController’. In the Controller you have to Create action method for the View.

In the above section I created a View – ‘Create.cshtml’. Now in the Controller I have to create not one but two versions of action methods for this View:

  • 1. First version of action method will be of HTTP GET type and will be invoked when the browser issues the request normally. This action method will be called when someone visits this link – /Employee/Create.
  • 2. Second version of action method will be of HTTP POST type and will be invoked when the form is submitted. This version of the action method will be responsible for receiving submitted data.

The names of both version of action methods will be same. The post version will however carry an HttpPost attribute.

So add these 2 versions of ‘Create’ action method on the Controller which will then look like as shown below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FirstApp.Models;
using Microsoft.AspNetCore.Mvc;

namespace FirstApp.Controllers
{
    public class EmployeeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        // HTTP GET VERSION
        public IActionResult Create()
        {
            return View();
        }

        // HTTP POST VERSION  
        [HttpPost]
        public IActionResult Create(Employee employee)
        {
            Repository.Create(employee);
            return View("Thanks",employee);
        }
    }
}

The HTTP GET version of ‘Create’ action method simply returns the View. It does not require any attribute like post version.

The HTTP POST of the ‘Create’ action method contains the HttpPost attribute. It also has a parameter of type ‘Employee’. When the form’s button is clicked this parameter automatically gets the value of all HTML tags filled by the user. This is done automatically by MVC Model Binding feature.

Next the Employee data (which is the forms data) is added to the repository and the returned statement returns the control to the ‘Thanks’ View along with the employee data.

The 1st parameter passed on the View – View(“Thanks”,employee) specifies the View name, here ‘Thanks.cshtml’. While the 2nd parameter specifies the Model data passed to the View, here employee data. This means, once the form is submitted, the ‘Thanks.cshtml’ is called to render.
Create Thanks.cshtml

Add Thanks View inside the Views ➤ Employee folder and add the below code to it:

@model Employee
@{
    ViewData["Title"] = "Thanks";
}

<h2>Thanks, @Model.Name</h2>

I just added @model Employee at the top because it will be receiving the Employee data.

Inside the h2 tag, a thanks message will be shown with the Employee Name – @Model.Name.

I have a basic working example ready now. So run your application and navigate to /Employee/Create on your browser.

You will see the form, fill it and click the submit button:

employee form mvc

On submitting you will see the thanks message with the employee name.

thanks message employee form

Display all Employees

So far the Create Employee feature is complete. In this section I will create the Read feature where details of all employees can be read.

I will use the Index action method which will return Repository.AllEmpoyees to the View. As you remember Repository.AllEmpoyees contains list of all employees.

The code for this is given below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FirstApp.Models;
using Microsoft.AspNetCore.Mvc;

namespace FirstApp.Controllers
{
    public class EmployeeController : Controller
    {
        public IActionResult Index()
        {
            return View(Repository.AllEmpoyees);
        }

        // Removed for clarity  
    }
}

Next, create the Index View inside the Views ➤ Employee folder and add the below code to it:

@model IEnumerable<Employee>
@{
    ViewData["Title"] = "Index";
}

<h2>Here is the list of Employees</h2>
<table style="width:50%">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Salary</th>
            <th>Department</th>
            <th>Sex</th>
        </tr>
    </thead>
    <tbody>
        @foreach (Employee e in Model)
        {
            <tr>
                <td>@e.Name</td>
                <td>@e.Age</td>
                <td>@e.Salary</td>
                <td>@e.Department</td>
                <td>@e.Sex</td>
            </tr>
        }
    </tbody>
</table>

Obviously the View has the model of type IEnumerable as it will receive list of Employees. To display all these Employees I have used HTML Table, in the table I am iterating all the employees using the foreach loop and displaying their data one by one inside the tbody element.

To test how this works create a few employees and then go to /Employee URL on your browser. You will see all Employees like the figure below:

all employees shown in view

Connect the Views through links

I don’t what to type in the URL on the browser in order to see the contents of a View. Now I will link them using anchor tags.

On the ‘Thanks.cshtml’ add the code line – View All Employees just before the h2 tag.

This line will create the anchor tag that will link to the Index View. The asp-action is a tag helper that tells anchor to link to the Index view of the same Controller where you are currently in.

The ‘Thanks.cshtml’ code will become:

@model Employee
@{
    ViewData["Title"] = "Thanks";
}
<a asp-action="Index">View All Employees</a>
<h2>Thanks, @Model.Name</h2>

In the same way add the anchor tag code – Create an Employees, to the Index View. This will link it to the ‘Create.cshtml’ View.

The ‘Index.cshtml’ code will become:

@model IEnumerable<Employee>
@{
    ViewData["Title"] = "Index";
}
<a asp-action="Create">Create an Employees</a>

<h2>Here is the list of Employees</h2>
<table style="width:50%">
    ...
</table>

Finally link the Create View to the Index View by adding this – View All Employees code.

The ‘Create.cshtml’ code will become:

@model Employee
@{
    ViewData["Title"] = "Create";
}
<a asp-action="Index">View All Employees</a>
<h2>Create</h2>
<form method="post">
    ...
</form>

The given image shows the anchor tags on each of the three Views:

view linked with anchor tags

Update Employee

In this section I will create Update Employee feature. The whole concept of update is to send the employee name to ‘Update’ action method in the form of query string. There I will fetch all the details of the employee that has the name as specified in the query string.

I will provide ‘Update’ link besides every employee displayed on the table in the Index View. So add a new td element inside the foreach block:

<td><a asp-action="Update" asp-route-empname="@e.Name">Update</a></td></span>

Now the Index View code will look like this:

@model IEnumerable<Employee>
@{
    ViewData["Title"] = "Index";
}
<a asp-action="Create">Create an Employees</a>

<h2>Here is the list of Employees</h2>
<table style="width:50%">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Salary</th>
            <th>Department</th>
            <th>Sex</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (Employee e in Model)
        {
            <tr>
                <td>@e.Name</td>
                <td>@e.Age</td>
                <td>@e.Salary</td>
                <td>@e.Department</td>
                <td>@e.Sex</td>
                <td><a asp-action="Update" asp-route-empname="@e.Name">Update</a></td>
            </tr>
        }
    </tbody>
</table>

The asp-route-* is a route tag helper that will create a query string by the name given at ‘*’, here it will be ‘empname’.

So the code – Update will create an anchor tag with the ‘href’ attribute to the ‘Update’ action method with ‘empname’ as query string. In short the ‘href’ of anchor will be – ‘/Update?empname=name-of-employee’.

Run the application and go to the Index View. You will see the update links along each employee as shown on the image below:

update links along all employees

Now go to your Controller and add the HTTP GET and HTTP POST versions of Update action method. They are given on the code below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FirstApp.Models;
using Microsoft.AspNetCore.Mvc;

namespace FirstApp.Controllers
{
    public class EmployeeController : Controller
    {
        // Removed for clarity

        public IActionResult Update(string empname)
        {
            Employee employee = Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault();
            return View(employee);
        }

        [HttpPost]
        public IActionResult Update(Employee employee, string empname)
        {
            Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Age = employee.Age;
            Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Salary = employee.Salary;
            Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Department = employee.Department;
            Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Sex = employee.Sex;
            Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Name = employee.Name;

            return RedirectToAction("Index");
        }
    }
}

In the HTTP GET version of Update action method, the parameter string empname will have the value of ‘empname’ in the query string. This is done automatically by MVC model binding feature.

I am then storing the employee details (in an employee object), of the one whose name matches ‘empname’, from the Repository using LINQ. In the end, the employee object is returned to the Update View.

In the HTTP POST version of the Update action method there are 2 parameters – Employee employee, string empname. The Employee object will contain the Employee data from the form when the submit button is clicked while empname will be contain the name of the employee in the query string.

I am then finding the employee details whose name matches ‘empname’ value, and updating its fields (Age, Salary, Department, Sex, Name) with the one provided in the ‘employee’ object.

In the end I am redirecting to HTTP GET action of Index action method using – RedirectToAction(“Index”).

Finally create the update view inside the Views ➤ Employee folder. The contents of the Update View is totally same to the Create View except for the – ViewData[“Title”] = “Update” and the <h2>Update</h2>.

The Update View is given below:

@model Employee
@{
    ViewData["Title"] = "Update";
}
<a asp-action="Index">View All Employees</a>
<h2>Update</h2>
<form method="post">
    <p>
        <label asp-for="Name">Your Name:</label>
        <input asp-for="Name" />
    </p>
    <p>
        <label asp-for="Age">Your Age:</label>
        <input asp-for="Age" />
    </p>
    <p>
        <label asp-for="Salary">Your Salary:</label>
        <input asp-for="Salary" />
    </p>
    <p>
        <label asp-for="Department">Your Department:</label>
        <select asp-for="Department">
            <option value="Development">Development</option>
            <option value="HR">HR</option>
            <option value="Research">Research</option>
        </select>
    </p>
    <p>
        <label asp-for="Sex">Your Sex:</label>
        <input type="radio" asp-for="Sex" value="M" />Male
        <input type="radio" asp-for="Sex" value="F" />Female
    </p>
    <p><button type="submit">Submit</button></p>
</form>

Delete Employee

To delete an employee from the repository, first create ‘Delete’ static method in the Repository.cs file.

using System.Collections.Generic;

namespace FirstApp.Models
{
    public static class Repository
    {
        // Removed for clarity

        public static void Delete(Employee employee)
        {
            allEmpoyees.Remove(employee);
        }
    }
}

Next add HTTP POST action method by name ‘Delete’ in the Controller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FirstApp.Models;
using Microsoft.AspNetCore.Mvc;

namespace FirstApp.Controllers
{
    public class EmployeeController : Controller
    {
        // Removed for clarity

        [HttpPost]
        public IActionResult Delete(string empname)
        {
            Employee employee = Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault();
            Repository.Delete(employee);
            return RedirectToAction("Index");
        }
    }
}

The Delete action method will be called on the form’s button click so I have added the ‘HttpPost’ attribute to it. It receives a variable ‘empname’ in its parameter which will be bound by model binding.

The Delete method fills the details of the employee in an Employee object then calls the ‘Delete’ method of the repository to remove it from there. In the end the browser is redirected to the HTTP GET method of the Index action method.

For calling the Delete action method go to the Index View and add a new td element inside the foreach block. Inside this td create a form element.

The form code is:

<form asp-action="Delete" method="post">
    <input type="hidden" name="empname" value="@e.Name" />
    <button type="submit">Delete</button>
</form>

This form has a button which when clicked will revoke the ‘Delete’ action method (HTTP POST version). The asp-action is a tag helper that is used to set the form’s action, which in this case is the ‘Delete’ action method.

The value of the hidden input tag, kept inside the form, is set to employee name. The name of this tag is kept as ‘empname’ same as that of the parameter of Delete action. This makes the parameter to get the value of this hidden input tag through the model binding feature.

Now the full code of Index View has become like that shown below:

@model IEnumerable<Employee>
@{
    ViewData["Title"] = "Index";
}
<a asp-action="Create">Create an Employees</a>

<h2>Here is the list of Employees</h2>
<table style="width:50%">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Salary</th>
            <th>Department</th>
            <th>Sex</th>
            <th></th>
            <th></th>          
        </tr>
    </thead>
    <tbody>
        @foreach (Employee e in Model)
        {
            <tr>
                <td>@e.Name</td>
                <td>@e.Age</td>
                <td>@e.Salary</td>
                <td>@e.Department</td>
                <td>@e.Sex</td>
                <td><a asp-action="Update" asp-route-empname="@e.Name">Update</a></td>
                <td>
                    <form asp-action="Delete" method="post">
                        <input type="hidden" name="empname" value="@e.Name" />
                        <button type="submit">Delete</button>
                    </form>
                </td>
            </tr>
        }
    </tbody>
</table>

You can check the working of the Delete feature by running your application and click the ‘Delete’ button against any of the Employee.

The below image shows how the delete buttons will look against each employee:

delete buttons along all employees

Adding Validations

You may have noticed that on the ‘Create Employee’ page the user can simply submit the form without filling any of the fields. So this will give rise to bad entries which you should prevent in your application. Here Validations will come out handy.

In ASP.NET Core MVC the Validations are done in the Model class. This means your validations are applied on one place but takes effect everywhere in the application. The validation rules are applied with attributes from the System.ComponentModel.DataAnnotations namespace.

Go to your ‘Employee.cs’ class in the Models folder and import the namespace – System.ComponentModel.DataAnnotations to it.

Add the attributes like shown on the modified ‘Employee.cs’ file below:

using System;
using System.ComponentModel.DataAnnotations;

namespace FirstApp.Models
{
    public class Employee
    {
        [Required(ErrorMessage = "Please enter your name")]
        public string Name { get; set; }

        [Range(16, 60, ErrorMessage = "Ages 16-60 only")]
        public int Age { get; set; }

        [RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Invalid, enter like # or #.##")]
        public decimal Salary { get; set; }

        public string Department { get; set; }

        [RegularExpression(@"^[MF]+$", ErrorMessage = "Select any one option")]
        public Char Sex { get; set; }
    }
}

ASP.NET Core MVC automatically detects the attributes and uses them to validate data during the model-binding process.

Understanding the different Attributes

I have used 3 different types of attributes here:

1. The Required attribute is used to specify that the field on which it is applied cannot contain null or empty. I applied them to the string property ‘Name’ so that MVC forces user to fill the ‘Name’ text box.

2. The Range attribute specify the numeric range value for the field. I applied it on the ‘Age’ field so that only ages from 16 to 60 are accepted by the text box.

3. The RegularExpression attribute specifies that the field value much match the Regular Expression value. I applied on the ‘Sex’ field with expression ^[MF]+$ so that user has to select radio button. Remember my radio buttons have value ‘M’ & ‘F’ so if user does not selects any of them then Regular Expression will fail and so will the validation.

Required attribute works only when the values are null or empty so I did not applied the Required attribute on Age and Salary. The reason is that, suppose if the user does not fills any value to these text boxes then the default value of 0 will be applied to the Age and Salary fields (default values both int and decimal types are 0).

The default value of char is ‘\0’ so the Required attribute is also useless for the Sex field.

The case of Department field is different. It gets applied on select control and so user cannot escape selecting an option.

To show these validation errors on the View, you add a control like ‘span’, ‘label’ or ‘div’ besides each of the controls which the user has to fill or select. You also have to bind this control to the validation error message associated with it (on model) using asp-validation-for tag helper.

Example: For the name field add the span element like this:

<p>
    <label asp-for="Name">Your Name:</label>
    <input asp-for="Name" />
    <span asp-validation-for="Name"></span>
</p>

Do this for wherever you have to show the validation message. So you update your Views – ‘Create.cshtml’ & ‘Update.cshtml’ files like shown below:

Create.cshtml

@model Employee
@{
    ViewData["Title"] = "Create";
}
<a asp-action="Index">View All Employees</a>
<h2>Create</h2>
<form method="post">
    <p>
        <label asp-for="Name">Your Name:</label>
        <input asp-for="Name" />
        <span asp-validation-for="Name"></span>
    </p>
    <p>
        <label asp-for="Age">Your Age:</label>
        <input asp-for="Age" />
        <span asp-validation-for="Age"></span>
    </p>
    <p>
        <label asp-for="Salary">Your Salary:</label>
        <input asp-for="Salary" />
        <span asp-validation-for="Salary"></span>
    </p>
    <p>
        <label asp-for="Department">Your Department:</label>
        <select asp-for="Department">
            <option value="Development">Development</option>
            <option value="HR">HR</option>
            <option value="Research">Research</option>
        </select>
        <span asp-validation-for="Department"></span>
    </p>
    <p>
        <label asp-for="Sex">Your Sex:</label>
        <input type="radio" asp-for="Sex" value="M" />Male
        <input type="radio" asp-for="Sex" value="F" />Female
        <span asp-validation-for="Sex"></span>
    </p>
    <p><button type="submit">Submit</button></p>
</form>

Update.cshtml

@model Employee
@{
    ViewData["Title"] = "Update";
}
<a asp-action="Index">View All Employees</a>
<h2>Update</h2>
<form method="post">
    <p>
        <label asp-for="Name">Your Name:</label>
        <input asp-for="Name" />
        <span asp-validation-for="Name"></span>
    </p>
    <p>
        <label asp-for="Age">Your Age:</label>
        <input asp-for="Age" />
        <span asp-validation-for="Age"></span>
    </p>
    <p>
        <label asp-for="Salary">Your Salary:</label>
        <input asp-for="Salary" />
        <span asp-validation-for="Salary"></span>
    </p>
    <p>
        <label asp-for="Department">Your Department:</label>
        <select asp-for="Department">
            <option value="Development">Development</option>
            <option value="HR">HR</option>
            <option value="Research">Research</option>
        </select>
        <span asp-validation-for="Department"></span>
    </p>
    <p>
        <label asp-for="Sex">Your Sex:</label>
        <input type="radio" asp-for="Sex" value="M" />Male
        <input type="radio" asp-for="Sex" value="F" />Female
        <span asp-validation-for="Sex"></span>
    </p>
    <p><button type="submit">Submit</button></p>
</form>

Finally I have to make the necessary changes on the Controller. Open your ‘Employee’ controller and change the HTTP POST versions of Create and Update actions like shown below:

[HttpPost]
public IActionResult Create(Employee employee)
{
    if (ModelState.IsValid)
    {
        Repository.Create(employee);
        return View("Thanks", employee);
    }
    else
        return View();
}

[HttpPost]
public IActionResult Update(Employee employee, string empname)
{
    if (ModelState.IsValid)
    {
        Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Age = employee.Age;
        Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Salary = employee.Salary;
        Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Department = employee.Department;
        Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Sex = employee.Sex;
        Repository.AllEmpoyees.Where(e => e.Name == empname).FirstOrDefault().Name = employee.Name;

        return RedirectToAction("Index");
    }
    else
        return View();
}

The main thing which I have done is adding an ‘if’ condition which checks whether ModelState is valid (if (ModelState.IsValid)). In ModelState, MVC keeps the details of the validations checks. If all validations passe then MVC makes ModelState valid.

Therefore if the ModelState is valid only then I am adding or updating the Employee in the Repository. This completes the validation section of MVC.

Try submitting the employee form without filling or selecting any value on the controls. You will see the validation errors like shown in the image below:

validation errors employee form

Adding Styles

To make the appearance of the application good you have to add some CSS Style.

You may ask where is the application’s Style Sheet? The answer is – open the _ViewStart.cshtml file located in the Views folder. This file contains the layout of all the Views in your application.

The _ViewStart.cshtml file’s code will look like:

@{
    Layout = "_Layout";
}

It specifies the Layout which is ‘_Layout.cshtml’ which is located inside the Views ➤Shared folder. Open the _Layout.cshtml file.

The code of _Layout.cshtml file is given below:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - FirstApp</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    .... Removed for clarity
</body>
</html>

It has the HTML Structure that gives the necessary design to all your Views. See inside the head area you will find 2 sections:

<environment include="Development">
</environment>

<environment exclude="Development">
</environment>

When you run your application in localhost then MVC includes only those files, that are inside the , in the head section. If the application is running online then only the files inside the are added to the head section. You will find they have a link to the application Style Sheet file – which is located inside the ‘wwwroot’ folder. So you now know where you have to place your CSS codes.

Open the ‘site.css’ file and add the following code to style the form and the table.

.container a {
    font-family: 'Adobe Arabic';
    font-size: 25px;
}

form p label {
    width: 10%;
}

form p input[type="text"], form p input[type="number"], form p select {
    width: 20%;
}

form p span {
    width: 20%;
    color: Red;
}

form p button, table button {
    background-color: #006bff;
    color: #FFF;
}

form p .input-validation-error {
    border: 1px solid Red;
    background-color: #fee;
}

table {
    border: solid 1px #ff6a00;
}

    table thead {
        background: #b6ff00;
    }

    table td, table th {
        padding: 10px;
    }

Also to notice here is that ASP.NET Core MVC adds class=”input-validation-error” to input controls when validation fails. See below:

<input type="text" class="input-validation-error" data-val="true" data-val-required="Please enter your name" id="Name" name="Name" value="">

Therefore I added a red border to them though my CSS code below:

form p .input-validation-error {
    border: 1px solid Red;
    background-color: #fee;
}

Now the Create Employee page will look like this:

employee form after styling

And all the employees displayed on the table will look like this:

employee list after styling

You can download the full codes of this tutorial from the below link:

Download

Summary

This tutorial gives you are quick and an excellent picture of ASP.NET Core MVC and explains you how to quickly start working on this framework. I created a small ‘CRUD’ application which you can download from the download link.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "ASP.NET Core, jQuery, EF Core, SEO, jQuery, HTML" and more.