Blood bank module:
1. BloodBank.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace BloodBankServiceSystem.Models
public class BloodBank
[Key]
public int BloodBankID { get; set; }
[Required(ErrorMessage = "Blood Bank Name is required.")]
[StringLength(100, ErrorMessage = "Blood Bank Name cannot exceed 100 characters.")]
public string BloodBankName { get; set; }
[Required(ErrorMessage = "Address is required.")]
[StringLength(200, ErrorMessage = "Address cannot exceed 200 characters.")]
public string Address { get; set; }
[Required(ErrorMessage = "City is required.")]
[StringLength(100, ErrorMessage = "City cannot exceed 100 characters.")]
public string City { get; set; }
[Required(ErrorMessage = "State is required.")]
[StringLength(100, ErrorMessage = "State cannot exceed 100 characters.")]
public string State { get; set; }
[Required(ErrorMessage = "Contact Number is required.")]
[RegularExpression(@"^\d{10}$", ErrorMessage = "Contact Number must be 10 digits.")]
public string ContactNumber { get; set; }
[Required(ErrorMessage = "Email is required.")]
[EmailAddress(ErrorMessage = "Invalid Email Address.")]
public string Email { get; set; }
[Required(ErrorMessage = "Available Units are required.")]
[Range(0, int.MaxValue, ErrorMessage = "Available units must be a non-negative number.")]
public int AvailableUnits { get; set; }
[Required(ErrorMessage = "Last Stock Update date is required.")]
public DateTime LastStockUpdate { get; set; }
public ICollection<BloodInventory> BloodInventories { get; set; } = new
List<BloodInventory>();
public ICollection<BloodDonationCamp> BloodDonationCamps { get; set; } = new
List<BloodDonationCamp>();
}
2. BloodBankController.cs:
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using BloodBankServiceSystem.Data;
using BloodBankServiceSystem.Models;
using Microsoft.AspNetCore.Authorization;
namespace BloodBankServiceSystem.Controllers
[Authorize]
public class BloodBankController : Controller
private readonly IBloodBankRepository _bloodBankRepository;
public BloodBankController(IBloodBankRepository bloodBankRepository)
_bloodBankRepository = bloodBankRepository;
public async Task<IActionResult> Index()
var bloodBanks = await _bloodBankRepository.GetAllBloodBanksAsync();
return View(bloodBanks);
}
public async Task<IActionResult> Details(int id)
var bloodBank = await _bloodBankRepository.GetBloodBankByIdAsync(id);
if (bloodBank == null)
return NotFound();
return View(bloodBank);
public IActionResult Create()
return View();
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult>
Create([Bind("BloodBankID,BloodBankName,Address,City,State,ContactNumber,Email,Availabl
eUnits,LastStockUpdate")] BloodBank bloodBank)
if (ModelState.IsValid)
var existingByName = await
_bloodBankRepository.GetBloodBankByNameAsync(bloodBank.BloodBankName);
if (existingByName != null)
{
ModelState.AddModelError("BloodBankName", "Blood Bank with this name already
exists.");
return View(bloodBank);
var existingByContact = await
_bloodBankRepository.GetBloodBankByContactNumberAsync(bloodBank.ContactNumber);
if (existingByContact != null)
ModelState.AddModelError("ContactNumber", "Blood Bank with this contact number
already exists.");
return View(bloodBank);
await _bloodBankRepository.AddBloodBankAsync(bloodBank);
return RedirectToAction(nameof(Index));
return View(bloodBank);
public async Task<IActionResult> Edit(int id)
var bloodBank = await _bloodBankRepository.GetBloodBankByIdAsync(id);
if (bloodBank == null)
return NotFound();
return View(bloodBank);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id,
[Bind("BloodBankID,BloodBankName,Address,City,State,ContactNumber,Email,AvailableUnits,L
astStockUpdate")] BloodBank bloodBank)
if (id != bloodBank.BloodBankID)
return NotFound();
if (ModelState.IsValid)
var existingByName = await
_bloodBankRepository.GetBloodBankByNameAsync(bloodBank.BloodBankName);
if (existingByName != null && existingByName.BloodBankID != bloodBank.BloodBankID)
ModelState.AddModelError("BloodBankName", "Blood Bank with this name already
exists.");
return View(bloodBank);
var existingByContact = await
_bloodBankRepository.GetBloodBankByContactNumberAsync(bloodBank.ContactNumber);
if (existingByContact != null && existingByContact.BloodBankID !=
bloodBank.BloodBankID)
{
ModelState.AddModelError("ContactNumber", "Blood Bank with this contact number
already exists.");
return View(bloodBank);
await _bloodBankRepository.UpdateBloodBankAsync(id, bloodBank);
return RedirectToAction(nameof(Index));
return View(bloodBank);
public async Task<IActionResult> Delete(int id)
var bloodBank = await _bloodBankRepository.GetBloodBankByIdAsync(id);
if (bloodBank == null)
return NotFound();
return View(bloodBank);
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
await _bloodBankRepository.DeleteBloodBankAsync(id);
return RedirectToAction(nameof(Index));
}
}
3. BloodBankRepository.cs:
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BloodBankServiceSystem.Models;
namespace BloodBankServiceSystem.Data
public class BloodBankRepository : IBloodBankRepository
private readonly ApplicationDbContext _context;
public BloodBankRepository(ApplicationDbContext context)
_context = context;
}
public async Task<List<BloodBank>> GetAllBloodBanksAsync()
return await _context.BloodBanks.ToListAsync();
public async Task<BloodBank> GetBloodBankByIdAsync(int id)
return await _context.BloodBanks.FindAsync(id);
public async Task<BloodBank> AddBloodBankAsync(BloodBank bloodBank)
var existingByName = await _context.BloodBanks.FirstOrDefaultAsync(b =>
b.BloodBankName == bloodBank.BloodBankName);
if (existingByName != null) return null;
var existingByContact = await _context.BloodBanks.FirstOrDefaultAsync(b =>
b.ContactNumber == bloodBank.ContactNumber);
if (existingByContact != null) return null;
await _context.BloodBanks.AddAsync(bloodBank);
await _context.SaveChangesAsync();
return bloodBank;
public async Task<BloodBank> UpdateBloodBankAsync(int id, BloodBank bloodBank)
{
if (id != bloodBank.BloodBankID) return null;
var existingByName = await _context.BloodBanks.FirstOrDefaultAsync(b =>
b.BloodBankName == bloodBank.BloodBankName && b.BloodBankID != id);
if (existingByName != null) return null;
var existingByContact = await _context.BloodBanks.FirstOrDefaultAsync(b =>
b.ContactNumber == bloodBank.ContactNumber && b.BloodBankID != id);
if (existingByContact != null) return null;
_context.Entry(bloodBank).State = EntityState.Modified;
await _context.SaveChangesAsync();
return bloodBank;
public async Task<bool> DeleteBloodBankAsync(int id)
var bloodBank = await _context.BloodBanks.FindAsync(id);
if (bloodBank != null)
_context.BloodBanks.Remove(bloodBank);
await _context.SaveChangesAsync();
return true;
return false;
public async Task<BloodBank> GetBloodBankByNameAsync(string name)
{
return await _context.BloodBanks.FirstOrDefaultAsync(b => b.BloodBankName == name);
public async Task<BloodBank> GetBloodBankByContactNumberAsync(string
contactNumber)
return await _context.BloodBanks.FirstOrDefaultAsync(b => b.ContactNumber ==
contactNumber);
4. IBloodBankRepository.cs:
using System.Collections.Generic;
using System.Threading.Tasks;
using BloodBankServiceSystem.Models;
namespace BloodBankServiceSystem.Data
public interface IBloodBankRepository
{
Task<List<BloodBank>> GetAllBloodBanksAsync();
Task<BloodBank> GetBloodBankByIdAsync(int id);
Task<BloodBank> GetBloodBankByNameAsync(string name);
Task<BloodBank> GetBloodBankByContactNumberAsync(string contactNumber);
Task<BloodBank> AddBloodBankAsync(BloodBank bloodBank);
Task<BloodBank> UpdateBloodBankAsync(int id, BloodBank bloodBank);
Task<bool> DeleteBloodBankAsync(int id);
5. BloodBankApiController.cs:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using BloodBankServiceSystem.Data;
using BloodBankServiceSystem.Models;
using Microsoft.AspNetCore.Http;
namespace BloodBankServiceSystem.Controllers.Api
[Route("api/[controller]")]
[ApiController]
public class BloodBankApiController : ControllerBase
private readonly IBloodBankRepository _bloodBankRepository;
public BloodBankApiController(IBloodBankRepository bloodBankRepository)
_bloodBankRepository = bloodBankRepository;
// GET: api/BloodBankApi
[HttpGet]
public async Task<ActionResult<IEnumerable<BloodBank>>> GetAll()
var bloodBanks = await _bloodBankRepository.GetAllBloodBanksAsync();
return Ok(bloodBanks);
// GET: api/BloodBankApi/5
[HttpGet("{id}")]
public async Task<ActionResult<BloodBank>> GetById(int id)
{
var bloodBank = await _bloodBankRepository.GetBloodBankByIdAsync(id);
if (bloodBank == null)
return NotFound(new { message = "Blood bank not found" });
return Ok(bloodBank);
// POST: api/BloodBankApi
[HttpPost]
public async Task<ActionResult<BloodBank>> Create([FromBody] BloodBank bloodBank)
if (!ModelState.IsValid)
return BadRequest(ModelState);
await _bloodBankRepository.AddBloodBankAsync(bloodBank);
return CreatedAtAction(nameof(GetById), new { id = bloodBank.BloodBankID }, bloodBank);
// PUT: api/BloodBankApi/5
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, [FromBody] BloodBank bloodBank)
{
if (id != bloodBank.BloodBankID)
return BadRequest(new { message = "ID mismatch" });
await _bloodBankRepository.UpdateBloodBankAsync(id, bloodBank);
return NoContent();
// DELETE: api/BloodBankApi/5
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
var bloodBank = await _bloodBankRepository.GetBloodBankByIdAsync(id);
if (bloodBank == null)
return NotFound(new { message = "Blood bank not found" });
await _bloodBankRepository.DeleteBloodBankAsync(id);
return NoContent();
}
Views ---> BloodBank ------> Create.cshtml:
@model BloodBankServiceSystem.Models.BloodBank
@{
ViewData["Title"] = "Create Blood Bank";
<div class="container mt-5">
<div class="row">
<div class="col-md-12 text-center mb-4">
<h2 class="display-5 text-danger font-weight-bold animate__animated animate__fadeIn">
<i class="fas fa-plus-circle"></i> Create Blood Bank
</h2>
<hr class="my-4">
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-lg">
<div class="card-body px-5 py-4">
<form asp-action="Create" method="post">
<div class="form-group mb-4">
<label asp-for="BloodBankName" class="font-weight-bold text-dark">
<i class="fas fa-hospital"></i> Blood Bank Name
</label>
<input asp-for="BloodBankName" class="form-control shadow-sm" placeholder="Enter
name" />
<span asp-validation-for="BloodBankName" class="text-danger"></span>
</div>
<div class="form-group mb-4">
<label asp-for="Address" class="font-weight-bold text-dark">
<i class="fas fa-map-marker-alt"></i> Address
</label>
<input asp-for="Address" class="form-control shadow-sm" placeholder="Enter address"
id="addressInput" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group mb-4">
<label asp-for="State" class="font-weight-bold text-dark">
<i class="fas fa-map"></i> State
</label>
<select asp-for="State" class="form-control shadow-sm" id="stateDropdown">
<option value="">Select State</option>
<option value="Andhra Pradesh">Andhra Pradesh</option>
<option value="Telangana">Telangana</option>
<option value="Karnataka">Karnataka</option>
<option value="Tamil Nadu">Tamil Nadu</option>
<option value="Maharashtra">Maharashtra</option>
</select>
<span asp-validation-for="State" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-4">
<label asp-for="City" class="font-weight-bold text-dark">
<i class="fas fa-city"></i> City
</label>
<select asp-for="City" class="form-control shadow-sm" id="cityDropdown">
<option value="">Select City</option>
<!-- Cities will be populated via JavaScript based on state selection -->
</select>
<span asp-validation-for="City" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group mb-4">
<label asp-for="ContactNumber" class="font-weight-bold text-dark">
<i class="fas fa-phone-alt"></i> Contact Number
</label>
<input asp-for="ContactNumber" class="form-control shadow-sm" placeholder="Enter
contact" />
<span asp-validation-for="ContactNumber" class="text-danger"></span>
</div>
<div class="form-group mb-4">
<label asp-for="Email" class="font-weight-bold text-dark">
<i class="fas fa-envelope"></i> Email
</label>
<input asp-for="Email" class="form-control shadow-sm" placeholder="Enter email" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group mb-4">
<label class="font-weight-bold text-dark">
<i class="fas fa-flask"></i> Available Blood Units
</label>
<div class="blood-group-inputs">
@foreach (var bloodGroup in new[] { "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" })
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">@bloodGroup</span>
</div>
<input type="number" class="form-control" name="AvailableUnits[@bloodGroup]"
placeholder="Units" min="0" value="0">
</div>
</div>
</div>
<div class="form-group mb-4">
<label asp-for="LastStockUpdate" class="font-weight-bold text-dark">
<i class="fas fa-calendar-alt"></i> Last Stock Update
</label>
<input asp-for="LastStockUpdate" class="form-control shadow-sm"
type="datetime-local" />
<span asp-validation-for="LastStockUpdate" class="text-danger"></span>
</div>
<div class="text-center mt-5">
<button type="submit" class="btn btn-danger btn-lg shadow-lg px-4">
<i class="fas fa-save"></i> Save
</button>
<a asp-action="Index" class="btn btn-secondary btn-lg ml-3 shadow-lg">
<i class="fas fa-arrow-left"></i> Back to List
</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
// State-City mapping
const cityMap = {
"Andhra Pradesh": ["Kadapa", "Visakhapatnam", "Vijayawada", "Guntur", "Tirupati"],
"Telangana": ["Hyderabad", "Warangal", "Karimnagar", "Nizamabad", "Khammam"],
"Karnataka": ["Bangalore", "Mysore", "Hubli", "Mangalore", "Belgaum"],
"Tamil Nadu": ["Chennai", "Coimbatore", "Madurai", "Tiruchirappalli", "Salem"],
"Maharashtra": ["Mumbai", "Pune", "Nagpur", "Nashik", "Aurangabad"]
};
// Update cities when state changes
$('#stateDropdown').change(function() {
const selectedState = $(this).val();
const cityDropdown = $('#cityDropdown');
cityDropdown.empty();
cityDropdown.append('<option value="">Select City</option>');
if (selectedState && cityMap[selectedState]) {
cityMap[selectedState].forEach(city => {
cityDropdown.append(`<option value="${city}">${city}</option>`);
});
});
// Format address without extra commas
$('#addressInput').blur(function() {
let address = $(this).val().trim();
// Remove any sequence of commas and spaces and replace with single comma
address = address.replace(/[, ]+/g, ' ').replace(/ ,/g, ',').trim();
$(this).val(address);
});
</script>
<style>
.form-control:focus {
border-color: #dc3545;
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
button:hover, a.btn:hover {
transform: translateY(-2px);
transition: transform 0.2s ease-in-out;
.card {
border-radius: 1rem;
label i {
margin-right: 5px;
}
.blood-group-inputs .input-group-text {
min-width: 50px;
justify-content: center;
background-color: #f8f9fa;
.blood-group-inputs .form-control {
max-width: 100px;
</style>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
Views ---> BloodBank ------> Delete.cshtml:
@model BloodBankServiceSystem.Models.BloodBank
@{
ViewData["Title"] = "Delete Blood Bank";
}
<div class="container mt-5">
<div class="row">
<div class="col-md-12 text-center mb-4">
<h2 class="display-5 text-danger font-weight-bold animate__animated animate__fadeIn">
<i class="fas fa-exclamation-triangle"></i> Delete Blood Bank
</h2>
<p class="lead text-muted animate__animated animate__fadeIn">
Are you sure? This action is <strong>irreversible</strong>.
</p>
<hr class="my-4">
</div>
</div>
<div cl