Content

  • Add Interfaces for State & District
  • Implement Interfaces for State & District
  • Inversion of Control (IOC)
  • Register Repositories using DI in program.cs
  • Using Repositories in Controller
  • Read & Create using Repository and adding Views
  • Edit & Delete using Repository and adding Views
  • ViewBag
  • ViewData
  • TempData
  • Difference between- ViewBag, ViewData, TempData
  • Read & Create States using Repository and adding Views
  • Eager Loading in EF Core
  • Edit & Delete States using Repository and adding Views
  • District CRUD operations using Repository and adding Views

Add Interfaces for State & District

Code

Inteface File: State Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Test.Entities;

namespace Test.Repositories.Interfaces
{
    public interface IStateRepo
    {
        IEnumerable<State> GetAll();

        State GetById(int id);

        void Save(State state);

        void Edit(State state);

        void RemoveData(State state);
    }
}

Inteface File: District Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Test.Entities;

namespace Test.Repositories.Interfaces
{
    public interface IDistrictRepo
    {
        IEnumerable<District> GetAll();

        District GetById(int id);

        void Save(District district);

        void Edit(District district);

        void RemoveData(District district);
    }
}

Implement Interfaces for State & District

Code:

Class File: State Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Test.Entities;
using Test.Repositories.Interfaces;

namespace Test.Repositories.Implementations
{
    public class StateRepo : IStateRepo
    {
        private readonly ApplicationDbContext _context;

        public StateRepo(ApplicationDbContext context)
        {
            _context = context;
        }

        public void Edit(State state)
        {
            _context.States.Update(state);
            _context.SaveChanges();
        }

        public IEnumerable<State> GetAll()
        {
            var states= _context.States.ToList();
            return states;
        }

        public State GetById(int id)
        {
            var state = _context.States.Find(id);
            return state;
        }

        public void RemoveData(State state)
        {
            _context.States.Remove(state);
            _context.SaveChanges();
        }

        public void Save(State state)
        {
            _context.States.Add(state);
            _context.SaveChanges();
        }
    }
}

Class File: District Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Test.Entities;
using Test.Repositories.Interfaces;

namespace Test.Repositories.Implementations
{
    public class DistrictRepo : IDistrictRepo
    {
        private readonly ApplicationDbContext _context;

        public DistrictRepo(ApplicationDbContext context)
        {
            _context = context;
        }

        public void Edit(District district)
        {
            _context.Districts.Update(district);
            _context.SaveChanges();
        }

        public IEnumerable<District> GetAll()
        {
            var cities = _context.Districts.ToList();
            return cities;
        }

        public District GetById(int id)
        {
            var city = _context.Districts.Find(id);
            return city;
        }

        public void RemoveData(District district)
        {
            _context.Districts.Remove(district);    
            _context.SaveChanges();
        }

        public void Save(District district)
        {
            _context.Districts.Add(district);
            _context.SaveChanges();
        }
    }
}

Inversion of Control

  • Inversion of Control is a principle in software engineering where the control of object creation and flow of control is shifted from the application code to an external container.
  • IOC is typically achieved through Dependency Injection (DI)
  • ASP.NET Core MVC provides a built-in DI container that manages the dependencies for your application. You can register your dependencies with this container during application startup, and the container will then inject these dependencies into the constructors of the classes that require them.

Register Repositories using DI in program.cs

To use repositories in Controller, we need to achieve IOC by registering these repositories using DI in program.cs

Example

Code: Program.cs File

//register repos to use IOC
builder.Services.AddScoped<ICountryRepo,CountryRepo>();
builder.Services.AddScoped<IStateRepo,StateRepo>();
builder.Services.AddScoped<IDistrictRepo,DistrictRepo>();

Using Repositories in Controller

  • Create Repository field in Controller
  • Inject Repository in Controller using constructor

Example: Controller File

using Microsoft.AspNetCore.Mvc;
using Test.Entities;
using Test.Repositories.Interfaces;

namespace Test.UI.Controllers
{
    public class CountryController : Controller
    {
        private readonly ICountryRepo _countryRepo;

        public CountryController(ICountryRepo countryRepo)
        {
            _countryRepo = countryRepo;
        }

        
    }
}

Read & Create using Repository and adding Views

Steps:

  1. Create Action Methods
  2. Use methods in repository to Add & Read records
  3. Add razor view with template
  4. Make required changes in view

Example: Controller File

using Microsoft.AspNetCore.Mvc;
using Test.Entities;
using Test.Repositories.Interfaces;

namespace Test.UI.Controllers
{
    public class CountryController : Controller
    {
        private readonly ICountryRepo _countryRepo;

        public CountryController(ICountryRepo countryRepo)
        {
            _countryRepo = countryRepo;
        }

        public IActionResult Index()
        {
            var countries = _countryRepo.GetAll();
            return View(countries);
        }

        [HttpGet]
        public IActionResult Create()
        {
            Country country = new Country();
            country.Name = "";
            return View(country);
        }

        [HttpPost]
        public IActionResult Create(Country country)
        {
            _countryRepo.Save(country);
            return RedirectToAction("Index");
        }
    }
}

Example: View File - Index

@model IEnumerable<Test.Entities.Country>

    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-action="Create">Add New Country</a>
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Id)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
    @foreach (var item in Model) {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Id)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                </td>
            </tr>
    }
        </tbody>
    </table>

Example: View File - Create

@model Test.Entities.Country

    @{
        ViewData["Title"] = "Create";
    }
    
    <h1>Create</h1>
    
    <h4>Country</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Create">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
              
                <div class="form-group">
                    <label asp-for="Name" class="control-label"></label>
                    <input asp-for="Name" class="form-control" />
                    <span asp-validation-for="Name" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Create" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    }

Edit & Delete using Repository and adding Views

Steps:

  1. Create Action Methods
  2. Use methods in repository to Edit & Delete records
  3. Add razor view with template
  4. Make required changes in view

Example: Controller File

using Microsoft.AspNetCore.Mvc;
using Test.Entities;
using Test.Repositories.Interfaces;

namespace Test.UI.Controllers
{
    public class CountryController : Controller
    {
        private readonly ICountryRepo _countryRepo;

        public CountryController(ICountryRepo countryRepo)
        {
            _countryRepo = countryRepo;
        }

        public IActionResult Index()
        {
            var countries = _countryRepo.GetAll();
            return View(countries);
        }

        [HttpGet]
        public IActionResult Create()
        {
            Country country = new Country();
            country.Name = "";
            return View(country);
        }

        [HttpPost]
        public IActionResult Create(Country country)
        {
            _countryRepo.Save(country);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public IActionResult Edit(int id)
        {
            var country = _countryRepo.GetById(id);
            return View(country);
        }

        [HttpPost]
        public IActionResult Edit(Country country)
        {
            _countryRepo.Edit(country);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public IActionResult Delete(int id)
        {
            var country = _countryRepo.GetById(id);
            return View(country);
        }

        [HttpPost]
        public IActionResult Delete(Country country)
        {
            _countryRepo.RemoveData(country);
            return RedirectToAction("Index");
        }
    }
}

Example: View File - Edit

@model Test.Entities.Country

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>


<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                
                <input type="hidden" asp-for="Id" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Example: View File - Delete

@model Test.Entities.Country

@{
    ViewData["Title"] = "Delete";
}

<h1>Delete</h1>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Country</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Id)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Id)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Name)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Name)
        </dd>
    </dl>
    
    <form asp-action="Delete">
        <input type="submit" value="Delete" class="btn btn-danger" /> |
        <a asp-action="Index">Back to List</a>
    </form>
</div>

ViewBag

  • ViewBag is a dynamic property that allows you to pass data from a controller to a view. It's a dynamic object, meaning you can add properties to it on the fly without defining them beforehand. It's commonly used when you need to pass a small amount of data from a controller action to a corresponding view.
  • We can add any type of data to the ViewBag ? strings, integers, objects, etc.

Example : Controller File

using Microsoft.AspNetCore.Mvc;

namespace Test.UI.Controllers
{
    public class ConceptsController : Controller
    {
        public IActionResult Index()
        {
            ViewBag.Message = "Hello, ViewBag!";
            
            return View();
        }
    }
}

Example : View File

@{
    ViewData["Title"] = "Index";
}

<h1>@ViewBag.Message</h1>

ViewData

  • ViewData is a dictionary-like container that allows you to pass data from a controller to a view. Unlike ViewBag, ViewData is a dictionary of key-value pairs, and you need to explicitly cast data types when retrieving them in the view. It provides a way to pass data from the controller to the view without using strongly-typed models.

Example:Controller File

using Microsoft.AspNetCore.Mvc;

namespace Test.UI.Controllers
{
    public class ConceptsController : Controller
    {
        public IActionResult Index()
        {

            ViewData["Message"] = "Hello, ViewData!";

            return View();
        }
    }
}

Example:View File

@{
    ViewData["Title"] = "Index";
}

<h1>@ViewData["Message"]</h1>

TempData

  • TempData is a dictionary-like object used to pass data from the current request to the next request. Unlike ViewData and ViewBag, which are used to pass data from a controller to a view during the same request, TempData persists data for the subsequent request only. After the next request, the data stored in TempData is automatically removed.
  • @Model is used to display the data retrieved from TempData

Example:Controller File

using Microsoft.AspNetCore.Mvc;

namespace Test.UI.Controllers
{
    public class ConceptsController : Controller
    {
        public IActionResult Index()
        {
            TempData["Message"] = "Hello, TempData!";
            return View();
        }

        public IActionResult NextPage()
        {
            string message = TempData["Message"].ToString();
            return View("NextPage", message);
        }
    }
}

Example:View File (Next Page/Method)

@{
    ViewData["Title"] = "NextPage";
}

<h1>@Model</h1>

Difference between- ViewBag, ViewData, TempData

Feature ViewBag ViewData TempData
Usage Dynamic property Dictionary Dictionary
Scope Current request Current request Next request
Data Removal Not required, lasts for the current request Not required, lasts for the current request Automatically removed after the next request
Type Safety No compile-time checking No compile-time checking No compile-time checking
Storage Mechanism In memory In memory By default, in session (can be configured to use cookie-based temp data provider)
Example ViewBag.Message = "Hello, ViewBag!"; ViewData["Message"] = "Hello, ViewData!"; TempData["Message"] = "Hello, TempData!";

Read & Create States using Repository and adding Views

Steps:

  1. Create State Controller
  2. Inject Repositories (Country,State) in Controller using constructor
  3. Use method in repository to Read records
  4. In create method - Get countrylist from repository and store it in ViewBag
  5. Create razor views for Index & Create
  6. Make required changes in Views
  7. To show Country Name in state list, we have to update method in State repository

Example:Controller File

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Test.Entities;
using Test.Repositories.Implementations;
using Test.Repositories.Interfaces;

namespace Test.UI.Controllers
{
    public class StateController : Controller
    {
        private readonly IStateRepo _stateRepo;
        private readonly ICountryRepo _countryRepo;

        public StateController(IStateRepo stateRepo, ICountryRepo countryRepo)
        {
            _stateRepo = stateRepo;
            _countryRepo = countryRepo;
        }

        public IActionResult Index()
        {
            var states = _stateRepo.GetAll();
            return View(states);
        }

        

        [HttpGet]
        public IActionResult Create()
        {
            var countries = _countryRepo.GetAll();
            ViewBag.CountryList = new SelectList(countries, "Id", "Name");
            return View();
        }

        [HttpPost]
        public IActionResult Create(State state)
        {
            _stateRepo.Save(state);
            return RedirectToAction("Index");
        }

        
    }
}

Example:View File (Create)

@model Test.Entities.State

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

<h1>Create</h1>

<h4>State</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
           
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="CountryId" class="control-label"></label>
                <select asp-for="CountryId" asp-items="@ViewBag.CountryList" class="form-control">
                    <option selected disabled>Select Country</option>
                </select>
                <span asp-validation-for="CountryId" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

Example:View File (Index)

@model IEnumerable<Test.Entities.State>

    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-action="Create">Create New</a>
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Id)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                   Country
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
    @foreach (var item in Model) {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Id)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Country.Name)
                </td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                </td>
            </tr>
    }
        </tbody>
    </table>

Required update in Repository file (State)

public IEnumerable<State> GetAll()
{
    //including country to show country in state list
    var states= _context.States.Include(x=>x.Country).ToList();
    return states;
}

Eager Loading in EF Core

  • In Entity Framework (EF) Core, eager loading is a technique used to load related entities along with the main entity being queried in a single database round trip.
  • The Include method in EF Core is used to specify related entities that should be loaded along with the main entity. It allows you to specify navigation properties to be included in the query result.

Edit & Delete States using Repository and adding Views

Steps:

  1. Create Action Methods
  2. Use methods in repository to Edit & Delete records
  3. Add razor view with template
  4. Make required changes in view

Example: Controller File

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Test.Entities;
using Test.Repositories.Implementations;
using Test.Repositories.Interfaces;

namespace Test.UI.Controllers
{
    public class StateController : Controller
    {
        private readonly IStateRepo _stateRepo;
        private readonly ICountryRepo _countryRepo;

        public StateController(IStateRepo stateRepo, ICountryRepo countryRepo)
        {
            _stateRepo = stateRepo;
            _countryRepo = countryRepo;
        }

        public IActionResult Index()
        {
            var states = _stateRepo.GetAll();
            return View(states);
        }

        

        [HttpGet]
        public IActionResult Create()
        {
            var countries = _countryRepo.GetAll();
            ViewBag.CountryList = new SelectList(countries, "Id", "Name");
            return View();
        }

        [HttpPost]
        public IActionResult Create(State state)
        {
            _stateRepo.Save(state);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public IActionResult Edit(int id)
        {
            var countries = _countryRepo.GetAll();
            ViewBag.CountryList = new SelectList(countries, "Id", "Name");
            var state = _stateRepo.GetById(id);
            return View(state);
        }

        [HttpPost]
        public IActionResult Edit(State state)
        {
            _stateRepo.Edit(state);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public IActionResult Delete(int id)
        {
            var state = _stateRepo.GetById(id);
            return View(state);
        }



        [HttpPost]
        public IActionResult Delete(State state)
        {
            _stateRepo.RemoveData(state);
            return RedirectToAction("Index");
        }
    }
}

Example: View File - Edit

@model Test.Entities.State

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>State</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
               
                <input type="hidden" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="CountryId" class="control-label"></label>
                <select asp-for="CountryId" asp-items="@ViewBag.CountryList" class="form-control">
                    <option selected disabled>Select Country</option>
                </select>
                <span asp-validation-for="CountryId" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

Example: View File - Delete

@model Test.Entities.State

@{
    ViewData["Title"] = "Delete";
}

<h1>Delete</h1>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>State</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Id)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Id)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Name)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Name)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.CountryId)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.CountryId)
        </dd>
    </dl>
    
    <form asp-action="Delete">
        <input type="submit" value="Delete" class="btn btn-danger" /> |
        <a asp-action="Index">Back to List</a>
    </form>
</div>

District CRUD operations using Repository and adding Views

Steps:

  1. Create Action Methods
  2. Use methods in repository for CRUD operations
  3. Add razor view with template
  4. Make required changes in view

Example: Controller File

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Test.Entities;
using Test.Repositories.Implementations;
using Test.Repositories.Interfaces;

namespace Test.UI.Controllers
{
    public class DistrictController : Controller
    {
        private readonly IDistrictRepo _districtRepo;
        private readonly IStateRepo _stateRepo;

        public DistrictController(IDistrictRepo districtRepo, IStateRepo stateRepo)
        {
            _districtRepo = districtRepo;
            _stateRepo = stateRepo;
        }

        public IActionResult Index()
        {
            var districts = _districtRepo.GetAll();
            return View(districts);
        }

        [HttpGet]
        public IActionResult Create()
        {
            var states = _stateRepo.GetAll();
            ViewBag.StateList = new SelectList(states, "Id", "Name");
            return View();
        }

        [HttpPost]
        public IActionResult Create(District district)
        {
            _districtRepo.Save(district);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public IActionResult Edit(int id)
        {
            var states = _stateRepo.GetAll();
            ViewBag.StateList = new SelectList(states, "Id", "Name");
            var district = _districtRepo.GetById(id);
            return View(district);
        }

        [HttpPost]
        public IActionResult Edit(District district)
        {
            _districtRepo.Edit(district);
            return RedirectToAction("Index");
        }

        [HttpGet]
        public IActionResult Delete(int id)
        {
            var district = _districtRepo.GetById(id);
            return View(district);
        }



        [HttpPost]
        public IActionResult Delete(District district)
        {
            _districtRepo.RemoveData(district);
            return RedirectToAction("Index");
        }
    }
}

Example: View File - Index

@model IEnumerable<Test.Entities.District>

@{
    ViewData["Title"] = "Index";
}
    
<h1>Index</h1>
    
<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                State
            </th>
            <th>
                Country
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.State.Name)
            </td>
                <td>
                    @Html.DisplayFor(modelItem => item.State.Country.Name)
                </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
                    
                    @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
}
    </tbody>
</table>
        

Example: View File - Create

@model Test.Entities.District

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

<h1>Create</h1>

<h4>District</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
          
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="StateId" class="control-label"></label>
                <select asp-for="StateId" asp-items="@ViewBag.StateList" class="form-control">
                    <option selected disabled>Select State</option>
                </select>
                <span asp-validation-for="StateId" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

Example: View File - Edit

@model Test.Entities.District

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>District</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                
                <input type="hidden" asp-for="Id" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="StateId" class="control-label"></label>
                <select asp-for="StateId" asp-items="@ViewBag.StateList" class="form-control">
                    <option selected disabled>State</option>
                </select>
                <span asp-validation-for="StateId" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

Example: View File - Delete

@model Test.Entities.District

@{
    ViewData["Title"] = "Delete";
}

<h1>Delete</h1>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>District</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Id)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Id)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Name)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Name)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.StateId)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.StateId)
        </dd>
    </dl>
    
    <form asp-action="Delete">
        <input type="submit" value="Delete" class="btn btn-danger" /> |
        <a asp-action="Index">Back to List</a>
    </form>
</div>

Required update in Repository file (District)

 public IEnumerable GetAll()
 {
     var cities = _context.Districts.Include(x=>x.State).ThenInclude(y=>y.Country).ToList();
     return cities;
 }