CRUD Operation With Razor Pages In ASP.NET Core 2.0
What are Razor pages?
Razor Pages is a new feature of ASP.NET Core MVC that makes coding page-focused scenarios easier and more productive.
Where do we use Razor pages?
There are some pages in the application which are not too big where you are still required to create a controller and add action Method, along with that we need to add View.
In this part we can use Razor Pages which has code behind it . We just need to add a Razor Page and on view “Customer.cshtml” you can design your view and on the same page you can write code for handling requests such as get and Post, but if you think you want to separate it then you can use code behind “Customer.cshtml.cs”
Pre prerequisite for Razor Pages Application
- Install .Net Core 2.0 SDK
URL - https://www.microsoft.com/net/download/core
- Install Visual Studio 2017 version 15.3 or later
URL - https://www.visualstudio.com/downloads/
Visual Studio Community 2017
Free, fully-featured IDE for students, open-source and individual developers
Let’s start with the Create Razor Pages application.
Creating Razor page project
For creating a project just choose File Menu from Visual studio IDE then New, inside that, choose Project.
After choosing a project, a new dialog will pop up with the name “New Project”. In that, we are going to choose Visual C# Project Templates - Web - ASP.NET Core Web Application. Then, we are going to name the project as “RazorPagesDemo”.
After naming the project we are going click on OK button to create a project.
A new dialog will pop up for choosing templates for Creating “ASP.NET Core Web Application” in that template we are going to Create ASP.Net Core Razor Pages application. That's why we are going to choose “Web Application” and next we will have the option to choose framework 1.Net core or 2.Net Framework, and also ASP.NET Core Version. In that, we are going to choose “.Net Core” and “ASP.NET Core 2.0” as ASP.NET Core Version as click on OK button to create a project.
After clicking on OK button it will start to create a project.
Project Structure
You'll see some new project structure you in this project. There are no Model, View, Controller folders in this project.
You will only able to see Pages folder in this folder all Razor pages are stored.
One thing which is back again is a little code behind to make thinks little easier.
Yes Razor pages has Code behind.
In the first steps we are going to add a model folder and inside that folder we are going to add Customer Model.
Creating Model folder and Adding Customer Model in it
In this part, we are going to add a Model folder in “RazorPagesDemo” Project after adding folder next we are going to add Customer class (Model) in Models folder.
For details see below snapshot,
After adding Customer Model now next we are going to add a property to this class.
Adding Properties and DataAnnotations to Customer Model
In Razor pages, you can use the same DataAnnotations which are there in MVC.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace RazorPagesDemo.Models
{
[Table("CustomerTB")]
public class Customer
{
[Key]
public int CustomerID { get; set; }
[Required(ErrorMessage = "Enter Name")]
public string Name { get; set; }
[Required(ErrorMessage = "Enter Address")]
public string Address { get; set; }
[Required(ErrorMessage = "Enter Country Name")]
public string Country { get; set; }
[Required(ErrorMessage = "Enter City Name")]
public string City { get; set; }
[Required(ErrorMessage = "Enter City Phoneno")]
public string Phoneno { get; set; }
}
}
After completing with adding model and DataAnnotations next we are going to add Razor page.
Adding Razor Page to project
For adding Razor page just right click on Pages folder then select Add - inside that select New Item.
After selecting New Item a new dialog will pop up with name “New item” in that we are going to select Razor Page Item and name it as “Customer.cshtml” and click on add button.
After clicking on add button below is Pages folder structure in this part you can see “Customer.cshtml” View with “Customer.cshtml.cs” code behind which will have all handlers’ part to handle the request.
Understanding “Customer.cshtml” View
This “Customer.cshtml” file looks more like a Razor View.
In Customer.cshtml view the first thing you are going to see is @page directive which tells Razor view engine that this page is Razor page, not MVC View and it makes a page to handle request directly without going to the controller.
Next, you can see @model is a CustomerModel is a code-behind class name.
The CustomModel file name is the same name as Razor page file “Customer.cshtml.cs” just “.cs” appended at last.
This CustomModel class inherits from PageModel which make this class to handle the request.
Next thing you can see in CustomModel is OnGet Method (handler) which handles get request.
Let’s start will simple example then we are going to start with CRUD operation.
Displaying Message
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesDemo.Pages
{
public class CustomerModel : PageModel
{
public string WelcomeMessage { get; set; }
public void OnGet()
{
WelcomeMessage = "WelCome to Razor Pages by Saineshwar Bageri";
}
}
}
In this part, we have simply added a string with name WelcomeMessage and assigned value to it.
Next, on view, we are going to display a message in the following format.
Now Save Application and run.
And to access page just enter Page Name “Customer”.
URL - http://localhost:######/Customer
E.g. ####### (port number)
Wow, we have created our first razor page.
CRUD Operation with Razor Pages
The first thing we are going to do is Create Customer; for doing that we have added Customer Model in the Models folder.
Next, we are going to declare that model in CustomerModel class as below.
Code snippet of CustomerModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesDemo.Models;
namespace RazorPagesDemo.Pages
{
public class CustomerModel : PageModel
{
public Customer Customer { get; set; }
public void OnGet()
{
}
}
}
After declaring this Customer model in CustomerModel class now Customer Model is accessible on Razor page file (Customer.cshtml)
Now let’s Design View.
Adding input Controls on Customer.cshtml View
In this part, we have used New MVC tag helper to create input fields and we have added all model properties on View.
Note
if you want to learn about details of New Tag Helpers visit this link.
https://blogs.msdn.microsoft.com/cdndevs/2015/08/06/a-complete-guide-to-the-mvc-6-tag-helpers/
@page
@using RazorPagesDemo.Models @*namespace*@
@model CustomerModel
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<div class="container">
<h3>Add Customer</h3>
<hr />
<br />
<form method="post">
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Name"></label>
<input asp-for="Customer.Name" class="form-control" />
<span class="alert-danger" asp-validation-for="Customer.Name"></span>
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Address"></label>
<input asp-for="Customer.Address" class="form-control" />
<span class="alert-danger" asp-validation-for="Customer.Address"></span>
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Country"></label>
<input asp-for="Customer.Country" class="form-control" />
<span class="alert-danger" asp-validation-for="Customer.Country"></span>
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.City"></label>
<input asp-for="Customer.City" cl class="form-control" />
<span class="alert-danger" asp-validation-for="Customer.City"></span>
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Phoneno"></label>
<input asp-for="Customer.Phoneno" class="form-control" />
<span class="alert-danger" asp-validation-for="Customer.Phoneno"></span>
</div>
</div>
<br />
<input type="submit" value="Save" class="btn btn-primary" />
<a class="btn btn-default" href="/allcustomer">Cancel</a>
</form>
</div>
Now save Application and run project.
And to access page just enter Page Name “Customer”.
URL - http://localhost:######/Customer
Eg. ####### (port number)
Snapshot of Customer page
After entering URL the first request goes to OnGet handler.
While Debugging
Note - Handlers
There are 2 default handlers in Razor pages
- OnGet()
- OnPost()
If you want you can create your own handlers you can create I will show in the upcoming example.
After completing with Designing Razor Page file (“Customer.cshtml”) now let’s add another handler to handle post request.
Adding OnPost Handler
In this part, we are going to add Post Handler to get all data which is filled by the user.
We have added OnPost handler but it is not filling data of model what we have posted.
While Debugging
For binding data, we need to add [BindProperty] attribute on the (Customer) property we declare in CustomerModel class.
If we try to Post model again then we are going to get model populated with values. Let’s save these values in the database.
Database Part
I have created a database with the name “CustomerDB” and in that, it has “CustomerTB” table.
First thing for saving data in Database we need an ORM we are going to use “Entity framework core”
Installing package for Entity framework core from NuGet
To install the package, just right click on the project (RazorPagesDemo) and then select Manage NuGet package. The below dialog of NuGet Package Manager will pop up.
In the browse tab, type “Microsoft.EntityFrameworkCore.SqlServer” in the search box and just click on Install button.
Microsoft.EntityFrameworkCore.SqlServer
Adding Connection string and Setting up DbContext
After adding a reference, now add a connection string in appsetting.json file.
Now, let’s add a class with the name DatabaseContext in Models folder.
For adding a model, just right click on Models folder. Then, select Add - Class. An "Add New Item" dialog will pop up with default class selected. Name the class as DatabaseContext and click on Add button
After adding a DatabaseContext class, next, we are going to inherit DbContext class.
After inheriting with DbContext, next we are creating a constructor which takes DbContextOptions as an input parameter and also inherits the base class constructor (: base(options)) [DbContext].
Code snippet of DatabaseContext class
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RazorPagesDemo.Models
{
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
}
}
Next, we are going to add a new Service in Startup.cs class for injecting dependency.
Now, whenever you use DatabaseContext class, DbContext instance will be injected there.
After adding CustomerTB Model, in our next step, we are going to add DbSet of all models in DatabaseContext class.
Adding DbSet for CustomerTB Model in DatabaseContext class
Now, let's add DbSet for CustomerTB Model in DatabaseContext class, as shown below.
After adding DbSet in DatabaseContext class next we are going to add a constructor in CustomerModel class.
Setting up Dependency injection at CustomerModel class
In this part wherever we use DatabaseContext class, DbContext instance will be injected there.
Now using (“_Context”) object we can save data in the database, let’s make a change in OnPost handler to save data in the database.
Below snapshot, you can see we have made changes in OnPost handler
Code snippet of CustomerModel class
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesDemo.Models;
namespace RazorPagesDemo.Pages
{
public class CustomerModel : PageModel
{
DatabaseContext _Context;
public CustomerModel(DatabaseContext databasecontext)
{
_Context = databasecontext;
}
[BindProperty]
public Customer Customer { get; set; }
public void OnGet()
{
}
public ActionResult OnPost()
{
var customer = Customer;
if (!ModelState.IsValid)
{
return Page(); // return page
}
customer.CustomerID = 0;
var result = _Context.Add(customer);
_Context.SaveChanges(); // Saving Data in database
return RedirectToPage("AllCustomer");
}
}
}
Now save Application and run project.
And to access page just enter Page Name “Customer”.
URL - http://localhost:######/Customer Eg. ####### (port number)
Now on save button data will be saved in the database.
Database Output
Now we have completed adding part let’s add another Razor Page to display all customers (AllCustomer).
Adding All Customer Razor page
In this part, we are going to add another razor page to display All Customer which is saved in the database.
Adding new razor page in same way as we added customer Razor page
After adding AllCustomer.cshtml Razor page next we are going to adding Constructor and OnGet Handler
Adding Constructor and OnGet Handler
In this part onGet Handler we are going to get all customer details from the database and assign those values to CustomerList and this CustomerList on razor page we are going to iterate and display customer details.
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesDemo.Models;
using System.Collections.Generic;
using System.Linq;
namespace RazorPagesDemo.Pages
{
public class AllCustomerModel : PageModel
{
DatabaseContext _Context;
public AllCustomerModel(DatabaseContext databasecontext)
{
_Context = databasecontext;
}
public List<Customer> CustomerList { get; set; }
public void OnGet()
{
var data = (from customerlist in _Context.CustomerTB
select customerlist).ToList();
CustomerList = data;
}
}
}
Adding AllCustomer.cshtml
On AllCustomer razor page view we are going to declare @page directive after that namespace and at last
@model which is “AllCustomerModel”
Now we are going to Iterate data (CustomerList).
Code snippet of AllCustomerModel.cshtml
@page
@using RazorPagesDemo.Models
@model AllCustomerModel
<h2>Index</h2>
<p>
<a asp-page="Customer">Create New Customer</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayName("Name")
</th>
<th>
@Html.DisplayName("Address")
</th>
<th>
@Html.DisplayName("Country")
</th>
<th>
@Html.DisplayName("City")
</th>
<th>
@Html.DisplayName("Phoneno")
</th>
<th>Edit | Delete</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.CustomerList)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.Country)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.Phoneno)
</td>
<td>
<a asp-page="./EditCustomer" asp-route-id="@item.CustomerID">Edit</a> |
<a asp-page="./AllCustomer" onclick="return confirm('Are you sure you want to delete this item?');" asp-page-handler="Delete" asp-route-id="@item.CustomerID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
While iterating CustomerList you might have seen a new tag helper which we have used for Creating link for Edit and Delete button.
Edit link
In edit link, we have just assign EditCustomer razor page name to “asp-page” property and “asp-route-id” we have assigned CustomerID to it, We haven't added EditCustomer razor page yet but we will soon.
<a asp-page="./EditCustomer" asp-route-id="@item.CustomerID">Edit</a>
Delete link
In Delete link we have just assigned AllCustomer razor page names to “asp-page” property and we have assigned CustomerID to “asp-route-id; " next we are going to assign “asp-page-handler” property which is a new one especially for Razor pages. Here we are going to add Handler name “Delete” which we are going to create in AllCustomer Razor page.
<a asp-page="./AllCustomer" onclick="return confirm('Are you sure you want to delete this item?');"
asp-page-handler="Delete" asp-route-id="@item.CustomerID">Delete</a>
Adding Delete Handler
In Razor pages, we have 2 default handlers, OnGet and OnPost but we can add custom handlers also to handle OnGet and OnPost request
Below is a snapshot of it.
Code snippet of Delete Handler
In this part, we are going add Delete handler “OnGetDelete” which take CustomerID as input.
After receiving CustomerID (id) next we are going get Customer details from the database by passing CustomerID (id) and pass it to remove method to delete it and finally we redirect after deleting to the All Customer page.
public ActionResult OnGetDelete(int? id)
{
if (id != null)
{
var data = (from customer in _Context.CustomerTB
where customer.CustomerID == id
select customer).SingleOrDefault();
_Context.Remove(data);
_Context.SaveChanges();
}
return RedirectToPage("AllCustomer");
}
Now save the application and run it.
Access AllCustomer page.
Now if you see delete link by hovering it you can see we are passing id (CustomerId) and along with that we are also passing handler name (“Delete”)
e.g. http://localhost:49989/AllCustomer?id=2&handler=Delete
Finally, we have created delete handler the last thing that remains in CRUD operation is Edit Customer (Update) let’s start adding EditCustomer Razor page.
Adding EditCustomer page
In this part, we are going to add another Razor page to Edit Customer Details which is saved in the database.
Adding new Razor page in the same way as we add customer razor page
After adding EditCustomer.cshtml Razor page next we are going to adding Constructor and OnGet Handler
Adding Constructor and OnGet Handler
In this part onGet Handler, we are going to get CustomerID (id) from query string from that we are going to get Customer Details from the database and assign those values to Customer Model this model we are going to send to Edit Customer View.
Code snippet of Edit Customer Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesDemo.Models;
namespace RazorPagesDemo.Pages
{
public class EditCustomerModel : PageModel
{
DatabaseContext _Context;
public EditCustomerModel(DatabaseContext databasecontext)
{
_Context = databasecontext;
}
[BindProperty]
public Customer Customer { get; set; }
public void OnGet(int? id)
{
if (id != null)
{
var data = (from customer in _Context.CustomerTB
where customer.CustomerID == id
select customer).SingleOrDefault();
Customer = data;
}
}
}
}
Next, we are going to design Edit View for displaying records for editing.
Code snippet of Edit Customer Page
In this page we are creating edit page means we are going to show record and allow the user to edit details and update it.
The first thing you are going to see is @page"{id: int}" directive, which tells that page need "{id: int}"int id (CustomerID) then only it will accept requests else it will returns an HTTP 404 (not found) error.
It id (CustomerID) we are going to send from All Customer View Edit link.
Note
@page"{id: int}" it is kind of routing in Razor pages.
Link example: - http://localhost:49989/EditCustomer/1
@page "{id:int}"
@using RazorPagesDemo.Models
@model EditCustomerModel
<div class="container">
<h3>Edit Customer</h3>
<hr />
<br />
<form method="post">
<input asp-for="Customer.CustomerID" type="hidden" />
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Name"></label>
<input asp-for="Customer.Name" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Address"></label>
<input asp-for="Customer.Address" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Country"></label>
<input asp-for="Customer.Country" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.City"></label>
<input asp-for="Customer.City" cl class="form-control" />
</div>
</div>
<div class="row">
<div class="col-md-4">
<label asp-for="Customer.Phoneno"></label>
<input asp-for="Customer.Phoneno" class="form-control" />
</div>
</div>
<br />
<input type="submit" value="Save" class="btn btn-primary" />
<a class="btn btn-default" href="/allcustomer">Cancel</a>
</form>
</div>
Now save the application and run.
Access All Customer page
Now hover edit link you can see URL which is generated (http://localhost:49989/EditCustomer/1) now click on Edit link it will display EditCustomer Page.
While debugging
Now we have completed Edit page OnGet Handler implementation which helps to display customer data in edit mode, next we need to update data; for doing that we need to Add Onpost Handler which will handle post request.
Code snippet of OnPost Request
In this part we are posting data which will update Customer model which we are going to check it is valid or not if it is not valid then we are going to return Page() which will show Error Message.
If it is valid then we are going to update data in the database and redirect page to AllCustomer Page.
Code snippet of Complete EditCustomerModel
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesDemo.Models;
using System.Linq;
namespace RazorPagesDemo.Pages
{
public class EditCustomerModel : PageModel
{
DatabaseContext _Context;
public EditCustomerModel(DatabaseContext databasecontext)
{
_Context = databasecontext;
}
[BindProperty]
public Customer Customer { get; set; }
public void OnGet(int? id)
{
if (id != null)
{
var data = (from customer in _Context.CustomerTB
where customer.CustomerID == id
select customer).SingleOrDefault();
Customer = data;
}
}
public ActionResult OnPost()
{
var customer = Customer;
if (!ModelState.IsValid)
{
return Page();
}
_Context.Entry(customer).Property(x => x.Name).IsModified = true;
_Context.Entry(customer).Property(x => x.Phoneno).IsModified = true;
_Context.Entry(customer).Property(x => x.Address).IsModified = true;
_Context.Entry(customer).Property(x => x.City).IsModified = true;
_Context.Entry(customer).Property(x => x.Country).IsModified = true;
_Context.SaveChanges();
return RedirectToPage("AllCustomer");
}
}
}
Snapshot of Edit Customer Page
We have updated Name of Customer. Now let’s view All customer view -- that value is updated.
Wow, we have successfully Updated Customer Name in the database.
While debugging
Validation of Form
In Razor page validation is similar to MVC validation and there is no change in it. Just add DataAnnotations attribute on Model properties and on view starts its validation control.
Finally, we have learned, about Razor Pages and along with that how to do CRUD operations with Razor Pages in a step by step way. I hope you liked my article.