Menu Close

Create CRUD Operation using ReactJs and ASP.Net Core API- Starter Template

ASP.Net Core With Reactjs CRUD

This article will teach us about Create CRUD Operation using ReactJs and ASP.Net Core API. This post will show you how to use React JS to do CRUD (Create, Read, Update, and Delete) actions. A step-by-step article for CRUD operations in React Js will be provided. Please read my previous article on How to use Policy-based Authorization using JWT in .Net Core 7 and Angular.

Please find the complete Source code in this GitHub Link.

At the end of this article, we can see the output below. We constructed a CRUD example with ASP.Net Core and ReactJs, this is the first article about ReactJs in my blog post. In further posts, we will learn better structure and flow.

ReactJs-CRUD-APP-Starter-Template.gif

Prerequisites

Create ASP.Net Core With ReactJs Project

  • Launch the Visual Studio IDE and click on “Create new project”.
  • In the “Create new project” window, select “ASP.NET Core With ReactJs” from the template list.
  • Click Next. In the “Configure your new project” window, specify the name and location for the new project and then click Create.
  • In the “Create New ASP.NET Core with ReactJs” window shown next, select .NET Core as the runtime and .NET 7.0 from the drop-down list at the top. Select “API” as the project template to create a new ASP.NET Core API application. 
  • Ensure that the checkboxes “Enable Docker Support” are disabled s we won’t be using the default feature we will add it manually later and “Configure for HTTPS” are checked.
  • Ensure that Authentication is set as “No Authentication” as we won’t be using authentication either and Click Create.

ASPNetCore-ReactJs-template
  • We have created the ASP.NET Core with the React.Js project like this, and on the right-hand side, you can see the folder structure of the ReactJs Project.
  • The ClientApp is the React UI that will represent the presentation layer.
  • We have created the controller named Credit Card Controller that handles the CRUD.
  • DataContext is used to implement CRUD using Entity Framework Core.
ASPNetCore-ReactJs-Folder-Structure

Creating ASP.Net Core Web API CRUD

Here in this example, we are creating a Credit Card information CRUD. So below we are going to discuss the configuration of CRUD API.

Adding the required packages for creating CRUD

Install-Package Microsoft.EntityFrameworkCore-Version 7.0.1
Install-Package Microsoft.EntityFrameworkCore.SqlServer-Version 7.0.1
Install-Package Microsoft.EntityFrameworkCore.Tools-Version 7.0.1
Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design-Version 7.0.1

Creating Credit Model Using the below Properties

public class CreditCard
    {
        [Key]
        public int Id { get; set; }
        public string CardNumber { get; set; }
        public string CardName { get; set; }
        public string CardCvv { get; set; }
        public string ValidFromDateMonth { get; set; }
        public string ValidFromDateYear { get; set; }
        public string ValidExpiryDateMonth { get; set; }
        public string ValidExpiryDateYear { get; set; }
        public int? CreatedBy { get; set; }
        public int? UpdatedBy { get; set; }
        public DateTime? CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }
    }

Adding Database Connection String in the Appsettings.json

We have added the connection String below on appsettings.json.

"ConnectionStrings": {
    "DefaultConnection": "Server=JAYANTT;Database=CreditCardDB;Trusted_Connection=True;MultipleActiveResultSets=True;Encrypt=False;"
  }

Adding Context Class to generate the EF Code First Approach

  • We have created the DataContext class and implement the DbContext i.e form namespace Microsoft.EntityFrameworkCore.
  • Here we added Credit Card DbSet to add the table information.
 public class DataContext : DbContext
    {
        public DataContext (DbContextOptions<DataContext> options)
            : base(options)
        {
        }

        public DbSet<ASPNetCore_ReactJs_CRUD.Models.CreditCard> CreditCard { get; set; } = default!;
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
        }
    }

Getting the Connection string value in Program.cs

builder.Services.AddDbContext<DataContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string not found.")));

Adding Credit Controller for CRUD

The following REST APIs are created:

  • To list all Credit Cards: HTTP Get method
  • Get Credit Cards detail: HTTP Get method
  • Update Credit Cards detail: HTTP Put method
  • Create Credit Cards: HTTP Post method
  • Delete Credit Cards: HTTP Delete method
    [Route("api/[controller]")]
    [ApiController]
    public class CreditCardsController : ControllerBase
    {
        private readonly DataContext _context;

        public CreditCardsController(DataContext context)
        {
            _context = context;
        }

        // GET: api/CreditCards
        [HttpGet]
        public async Task<ActionResult<IEnumerable<CreditCard>>> GetCreditCard()
        {
          if (_context.CreditCard == null)
          {
              return NotFound();
          }
            return await _context.CreditCard.OrderByDescending(x => x.Id).ToListAsync();
        }

        // GET: api/CreditCards/5
        [HttpGet("{id}")]
        public async Task<ActionResult<CreditCard>> GetCreditCard(int id)
        {
          if (_context.CreditCard == null)
          {
              return NotFound();
          }
            var creditCard = await _context.CreditCard.FindAsync(id);

            if (creditCard == null)
            {
                return NotFound();
            }

            return creditCard;
        }

        // PUT: api/CreditCards/5
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPut("{id}")]
        public async Task<IActionResult> PutCreditCard(int id, CreditCard creditCard)
        {
            if (id != creditCard.Id)
            {
                return BadRequest();
            }

            _context.Entry(creditCard).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CreditCardExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // POST: api/CreditCards
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<CreditCard>> PostCreditCard(CreditCard creditCard)
        {
          if (_context.CreditCard == null)
          {
              return Problem("Entity set 'ASPNetCore_ReactJs_CRUDContext.CreditCard'  is null.");
          }
            _context.CreditCard.Add(creditCard);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetCreditCard", new { id = creditCard.Id }, creditCard);
        }

        // DELETE: api/CreditCards/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteCreditCard(int id)
        {
            if (_context.CreditCard == null)
            {
                return NotFound();
            }
            var creditCard = await _context.CreditCard.FindAsync(id);
            if (creditCard == null)
            {
                return NotFound();
            }

            _context.CreditCard.Remove(creditCard);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool CreditCardExists(int id)
        {
            return (_context.CreditCard?.Any(e => e.Id == id)).GetValueOrDefault();
        }
    }

Entity Framework Code First Migrations

Code first migrations here help you to create the database for us with the following tables Employees and Departments

// Add migrations
Add-Migration

// After migrations complete then run the below command, it create the database
Update-Database

After updating the above command we can able to create the database. For more details please follow this link to see how the CRUD operation is built in ASP.Net Core API using EF Core, Building CRUD REST APIs in ASP.Net Core 7.0 with EF.

Creating ReactJs CRUD Template

Below, we are going to discuss the ReactJs template that will handle the CRUD operation by calling the .NET Core API.

By running the application we can see the template where we can navigate to add the credit card information.

ASPNetCore-ReactJs-View-template

Adding Credit Card Information( AddCreditCard.js)

import React, { component, useState, useEffect, Redirect } from 'react';
import { useNavigate,useHistory  } from 'react-router-dom';
import './addcreditcard.css'
import { useForm } from 'react-hook-form';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBackspace, faBackward, faBook, faCoffee, faEdit, faEnvelopeOpenText, faPlus, faSdCard, faStickyNote, faTv, faVcard, faVials } from '@fortawesome/free-solid-svg-icons'
import { Link } from 'react-router-dom';
import { Collapse, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';


const mystyle = {
    cardicon: {
        fontSize: "130px"
    },
    carddipslay: {
        fontSize: "22px"
    },
    carddipslayheader: {
        fontSize: "22px"
    }
};

export default function AddCreditCard() {
    const navigate = useNavigate();
    const {
        register,
        handleSubmit,
        formState: { errors }
    } = useForm(
        {
            defaultValues: {
        cardnumber: "",
        cvv: "",
        validfromdatemonth: "",
        validfromdateyear: "",
        validexpirydatemonth: "",
        validexpirydateyear: "",
        cardname: ""
            }
        },);
    const onSubmit = async (data) => {
        const response = await fetch('https://localhost:7148/api/creditcards', {
            method: 'POST',
            body: JSON.stringify(data),
            headers: {
                'Content-Type': 'application/json'
            }
        });
        const result = await response.json();
        console.log(result);
        alert('Credit information saved successfully!!');
        navigate('/home');
    }
    return (        
        <form>

            <div class="row">
                <div class="col-sm-5 grid-margin stretch-card">
                    <div class="card">
                        <div class="card-body">

                            <p>CRUD (Create, Read, Update, Delete) operations refer to the fundamental operations used in database management and data manipulation. In the context of credit cards, CRUD operations can be applied to manage and interact with credit card data.</p>

                            <strong>Create a New Credit Card:</strong> This operation involves adding a new credit card to the system. You would collect necessary information such as cardholder name, card number, expiration date, CVV, and issuer information and then store it in a database.

                        </div>
                    </div>
                    <div class='mt-3 text-end'>
                        <NavLink tag={Link} className="text-dark" to="/home"> <FontAwesomeIcon icon={faBackward} /> Back to Card Details Page</NavLink>
                    </div>

                </div>

                <div class="col-sm-7 grid-margin stretch-card">
                    <div class="card">
                        <div class="card-body">
                            <h4 class="card-title text-center" style={mystyle.carddipslayheader}>Add the Credit Card Information</h4>
                            <hr />

                            <div class="table-responsive">
                                <table class="table table-hover">
                                    <thead>
                                        <tr>
                                            <th>Card Number</th>
                                            <th>CVV</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td>
                                                <input class="form-control" placeholder="Card Number"
                                                    type="number"
                                                    name="cardnumber"
                                                    {...register("cardnumber", {
                                                        required: true,
                                                        validate: {
                                                            checkLength: (value) => value.length <= 16 && value.length > 15
                                                        }
                                                    })}
                                                />
                                                {errors.cardnumber && errors.cardnumber.type === "required" && (
                                                    <p className="errorMsg">Card Number is required.</p>
                                                )}
                                                {errors.cardnumber?.type === "checkLength" && (
                                                    <p className="errorMsg">
                                                        Card Number should be 16 characters Length.
                                                    </p>
                                                )}
                                            </td>
                                            <td>
                                                <input class="form-control" placeholder="CVV"
                                                    type="number" maxLength="3" minLength="3"
                                                    name="CardCvv"
                                                    {...register("CardCvv", {
                                                        required: true,
                                                        validate: {
                                                            checkLength: (value) => value.length <= 3 && value.length > 2
                                                        }
                                                    })}
                                                />
                                                {errors.CardCvv && errors.CardCvv.type === "required" && (
                                                    <p className="errorMsg">CVV is required.</p>
                                                )}
                                                {errors.CardCvv?.type === "checkLength" && (
                                                    <p className="errorMsg">
                                                        CVV should be 3 characters Length.
                                                    </p>
                                                )}
                                            </td>

                                        </tr>
                                    </tbody>
                                </table>
                                <table class="table table-hover">
                                    <thead>
                                        <tr>
                                            <th>Valid From Date</th>
                                            <th></th>
                                            <th>Valid Expiry Date</th>
                                            <th></th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td>
                                                <input class="form-control" placeholder="MM"
                                                    type="number"
                                                    name="ValidFromDateMonth"
                                                    {...register("ValidFromDateMonth", {
                                                        required: true,
                                                        maxLength: 3
                                                    })}
                                                />
                                                {errors.ValidFromDateMonth && errors.ValidFromDateMonth.type === "required" && (
                                                    <p className="errorMsg">Month is required.</p>
                                                )}
                                            </td>
                                            <td>
                                                <input class="form-control" placeholder="YY"
                                                    type="number"
                                                    name="ValidFromDateYear"
                                                    {...register("ValidFromDateYear", {
                                                        required: true,
                                                        maxLength: 3
                                                    })}
                                                />
                                                {errors.ValidFromDateYear && errors.ValidFromDateYear.type === "required" && (
                                                    <p className="errorMsg">Year is required.</p>
                                                )}
                                            </td>
                                            <td>
                                                <input class="form-control" placeholder="MM"
                                                    type="number"
                                                    name="ValidExpiryDateMonth"
                                                    {...register("ValidExpiryDateMonth", {
                                                        required: true,

                                                    })}
                                                />
                                                {errors.ValidExpiryDateMonth && errors.ValidExpiryDateMonth.type === "required" && (
                                                    <p className="errorMsg">Month is required.</p>
                                                )}
                                            </td>
                                            <td>
                                                <input class="form-control" placeholder="YY"
                                                    type="number"
                                                    name="ValidExpiryDateYear"
                                                    {...register("ValidExpiryDateYear", {
                                                        required: true,

                                                    })}
                                                />
                                                {errors.ValidExpiryDateYear && errors.ValidExpiryDateYear.type === "required" && (
                                                    <p className="errorMsg">Year is required.</p>
                                                )}
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                                <table class="table table-hover">
                                    <thead>
                                        <tr>
                                            <th>Card Holder Name</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td>
                                                <input class="form-control" placeholder="Card Name"
                                                    type="text"
                                                    name="cardname"
                                                    {...register("cardname", {
                                                        required: true
                                                    })}
                                                />
                                                {errors.cardname && errors.cardname.type === "required" && (
                                                    <p className="errorMsg">Card Name is required.</p>
                                                )}
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                            <div class="text-center">
                                <button class="btn btn-primary" onClick={handleSubmit(onSubmit)}>Submit Card Information</button>
                            </div>
                            </div>
                        </div>
                    </div>
                </div>
        </form>
    )
}
  • Line #11-21: We have used the constant for styling.
  • Line #23: Here we used the function component instead of the class component. In the coming article, we will see the differentiation between function component vs class component.
  • Line #41-53: It calls the Credit Controller API to POST the data that we have entered on the below screen.
  • Line #54-231: is used for Adding credit information templates.

This is the output screen for Adding Credit information and submitting the card information.

ASPNetCore-ReactJs-add-credit-info

Viewing the Credit Card Information

  • Here the getresp() fetches the record and displays the credit information.
getresp(){
    const getresponse = fetch('https://localhost:7148/api/creditcards')  
    .then(response => response.json())  
    .then(data => {  
      this.setState({ creditcards: data });
    });
  }
  
  render() {
    
    const { creditcards } = this.state;

    const onDelete = async (id) => {
     // const navigate = useNavigate();
      const response = await fetch('https://localhost:7148/api/creditcards/' + id, {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json'
        }
      });
      alert('Credit information deleted successfully!!');
  this.getresp();
      //navigate('/home');
    }

To View credit card information look like below. Here we also highlighted the Edit and Delete Icon button that is responsible for Edit the Credit information along with deleting the record.

ASPNetCore-ReactJs-record-added

Edit Credit Information

Using the below piece of code we can make delete the records. For full source code you can check the GitHub link.

const response = await fetch('https://localhost:7148/api/creditcards/' + id, {
            method: 'PUT',
            body: JSON.stringify(data),
            headers: {
                'Content-Type': 'application/json'
            }
        });
        alert('Credit Information Edited Successfully!!');
        navigate('/home');

Delete Credit Information

 const onDelete = async (id) => {
     // const navigate = useNavigate();
      const response = await fetch('https://localhost:7148/api/creditcards/' + id, {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json'
        }
      });
      alert('Credit information deleted successfully!!');
  this.getresp();
    }

The Final Output screen as on below, where we can find the CRUD operation working fine as expected.

ReactJs CRUD Demo

The database screenshot is given below.

ASP.Net Core With Reactjs CRUD-DB

Please find the complete Source code in this GitHub Link.

Conclusion

In this article, we learned about Create CRUD Operation using ReactJs and ASP.Net Core API. A step-by-step article for CRUD operations in React JS.

Leave behind your valuable queries and suggestions in the comment section below. Also, if you think this article helps you, do not forget to share this with your developer community. Happy Coding 🙂

Latest Articles

SUPPORT ME

Buy Me A Coffee

Leave a Reply

Your email address will not be published. Required fields are marked *