Advertisement

Advertisement

How to Create Crud app using asp.net core Web Api thru Db First approach or reverse engineering

How to Create Crud App using asp.net core Web API thru Db First Approach

Step 1: Create a New .NET Core Web API Project

Step 2: Install Required NuGet Packages

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Tools (use for migration)
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Design (db 1st approach, already exist db then)

Step 3: Scaffold the Database

Scaffold-DbContext "Server=DESKTOP-9M9EDAA\SQLEXPRESS;Database=DbDot;Trusted_Connection=True; TrustServerCertificate = True; MultipleActiveResultSets = true" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
or
scaffold "Your_Connection_String" Microsoft.EntityFrameworkCore.SqlServer -o Models (o denotes Output Directory)

Your_Connection_String = "Server=.;Database=YourDatabase;Trusted_Connection=True; Trusted_Connection=True; MultipleActiveResultSet=True; TrustServerCertificate=True;"

Step 4: Modify DbContext file 

DbContext file ko modify karne ka main reason ye h ki OnConfiguring me connection string aa jata h jo ki security base pe sahi nhi h es liye OnConfiguring method ko replace kar de niche diye gaye sare code se.


private readonly IConfiguration _configuration;

public EcommDbContext(IConfiguration configuration , DbContextOptions<DbDotContext> options)
    : base(options)
{
    _configuration = configuration;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        var connectionString = _configuration.GetConnectionString("DbDot");
        optionsBuilder.UseSqlServer(connectionString);
    }
}

Step 5: Configure the Database in appsettings.json

"ConnectionStrings": { "DefaultConnection": "Server=DESKTOP-9M9EDAA\SQLEXPRESS;Database=DbDot;Trusted_Connection=True; TrustServerCertificate = True; MultipleActiveResultSets = true"  },

Step 6: Update Program.cs

builder.Services.AddDbContext<DbDotContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));


Step 7. Repo(folder->IRepository, Repository)

IRepository.cs

namespace DotApi.Repo
{
    public interface IRepository<T> where T : class
    {
        Task<IEnumerable<T>> GetAllAsync();
        Task<T> GetByIdAsync(int id);
        Task<T> AddAsync(T entity);
        Task<T> UpdateAsync(T entity);
        Task<bool> DeleteAsync(int id);
    }
}
Repository.cs

using DotApi.Data;
using Microsoft.EntityFrameworkCore;

namespace DotApi.Repo
{
    public class Repository<T> : IRepository<T> where T : class
    {
        private readonly AppDbContext _db;
        private readonly DbSet<T> _dbSet;
        public Repository(AppDbContext db) 
        { 
            _db = db;
            _dbSet = _db.Set<T>();
        }
        // Get All Records
        public async Task<IEnumerable<T>> GetAllAsync()
        {
            return await _dbSet.ToListAsync();
        }

        // Get a Single Record by ID
        public async Task<T> GetByIdAsync(int id)
        {
            return await _dbSet.FindAsync(id);
        }

        // Add a New Record
        public async Task<T> AddAsync(T item)
        {
            await _dbSet.AddAsync(item);
            await _db.SaveChangesAsync();
            return item;
        }

        // Update an Existing Record
        public async Task<T> UpdateAsync(T item)
        {
            _dbSet.Update(item);
            await _db.SaveChangesAsync();
            return item;
        }

        // Delete a Record by ID
        public async Task<bool> DeleteAsync(int id)
        {
            // Fetch the entity to delete
            var item = await _dbSet.FindAsync(id);
            if (item == null)
            {
                return false; // Entity not found
            }

            _dbSet.Remove(item);
            await _db.SaveChangesAsync();
            return true; // Successfully deleted
        }
    }
}

Step 8. Service (folder)

UserService.cs
using DotApi.Models;
using DotApi.Repo;
using Microsoft.Extensions.Logging;

namespace DotApi.Service
{
    public class UserService
    {
        private readonly IRepository<User> _repository;
        private readonly ILogger<UserService> _logger;

        public UserService(IRepository<User> repository, ILogger<UserService> logger)
        {
            _repository = repository;
            _logger = logger;
        }

        public async Task<IEnumerable<User>> GetAllUsersAsync()
        {
            try
            {
                return await _repository.GetAllAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching all Users.");
                throw;
            }
        }

        public async Task<User> GetUserAsync(int id)
        {
            try
            {
                var User = await _repository.GetByIdAsync(id);
                if (User == null)
                {
                    _logger.LogWarning($"User with ID {id} not found.");
                    throw new KeyNotFoundException($"User with ID {id} not found.");
                }
                return User;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error fetching User with ID {id}.");
                throw;
            }
        }

        public async Task<User> AddUserAsync(User User)
        {
            try
            {
                if (User == null || string.IsNullOrEmpty(User.Name))
                {
                    throw new ArgumentException("Invalid User data.");
                }
                return await _repository.AddAsync(User);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error adding User.");
                throw;
            }
        }

        public async Task<User> UpdateUserAsync(User User)
        {
            try
            {
                if (User == null || string.IsNullOrEmpty(User.Name))
                {
                    throw new ArgumentException("Invalid User data.");
                }
                return await _repository.UpdateAsync(User);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating User.");
                throw;
            }
        }

        public async Task<bool> DeleteUserAsync(int id)
        {
            try
            {
                var result = await _repository.DeleteAsync(id);
                if (!result)
                {
                    _logger.LogWarning($"User with ID {id} not found for deletion.");
                }
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error deleting User with ID {id}.");
                throw;
            }
        }
    }
}


Steps 8.Controllers(folder)

using DotApi.Models;
using DotApi.Service;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace DotApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly UserService _UserService;
        private readonly ILogger<UserController> _logger;

        public UserController(UserService UserService, ILogger<UserController> logger)
        {
            _UserService = UserService;
            _logger = logger;
        }

        [HttpGet]
        public async Task<IActionResult> GetAllUsers()
        {
            try
            {
                var Users = await _UserService.GetAllUsersAsync();
                return Ok(Users);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving all Users.");
                return StatusCode(StatusCodes.Status500InternalServerError, "Internal Server Error");
            }
        }

        [HttpGet("{id}")]
        public async Task<IActionResult> GetUser(int id)
        {
            try
            {
                var User = await _UserService.GetUserAsync(id);
                if (User == null)
                {
                    _logger.LogWarning($"User with ID {id} not found.");
                    return NotFound($"User with ID {id} not found.");
                }
                return Ok(User);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error retrieving User with ID {id}.");
                return StatusCode(StatusCodes.Status500InternalServerError, "Internal Server Error");
            }
        }

        [HttpPost]
        public async Task<IActionResult> PostUser(User User)
        {
            try
            {
                if (User == null || string.IsNullOrEmpty(User.Name))
                {
                    return BadRequest("Invalid User data.");
                }

                var newUser = await _UserService.AddUserAsync(User);
                return CreatedAtAction(nameof(GetUser), new { id = newUser.UserId }, newUser);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error adding User.");
                return StatusCode(StatusCodes.Status500InternalServerError, "Internal Server Error");
            }
        }

        [HttpPut]
        public async Task<IActionResult> PutUser(User User)
        {
            try
            {
                if (User == null || User.UserId <= 0)
                {
                    return BadRequest("Invalid User data.");
                }

                var updatedUser = await _UserService.UpdateUserAsync(User);
                return Ok(updatedUser);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating User.");
                return StatusCode(StatusCodes.Status500InternalServerError, "Internal Server Error");
            }
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteUser(int id)
        {
            try
            {
                var result = await _UserService.DeleteUserAsync(id);
                if (!result)
                {
                    return NotFound($"User with ID {id} not found for deletion.");
                }
                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error deleting User with ID {id}.");
                return StatusCode(StatusCodes.Status500InternalServerError, "Internal Server Error");
            }
        }
    }
}
===========================================================================================
For .NET 8, you don't need to install any of these packages manually for HttpClient or JSON handling. The functionality is built into the framework.

1.appsettings.json

"ApiSettings": {
    "BaseUrl" : "https://localhost:7140/"
}

2. Models (folder dragndrop from api)
3.Services (IUserApiService, UserApiService)

4.IUserApiService.cs
using DotWeb.Models;

namespace DotWeb.Service.UserService
{
    public interface IUserApiService
    {
        Task<IEnumerable<User>> GetAllUsersAsync();
        Task<User> GetUserByIdAsync(int id);
        Task<User> AddUserAsync(User User);
        Task<User> UpdateUserAsync(User User);
        Task<bool> DeleteUserAsync(int id);

    }
}
5.UserService.cs
using System.Net.Http;
using Newtonsoft.Json;
using DotWeb.Models;
using System.Text.Json;

namespace DotWeb.Service.UserService
{
    public class UserApiService
    {
        private readonly HttpClient _httpClient;
        public UserApiService(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        public async Task<IEnumerable<User>> GetAllUsersAsync()
        {
            var response = await _httpClient.GetAsync("api/User");
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            return System.Text.Json.JsonSerializer.Deserialize<IEnumerable<User>>(content, options);


        }

        public async Task<User> GetUserByIdAsync(int id)
        {
            var response = await _httpClient.GetAsync($"api/User/{id}");
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
            return  System.Text.Json.JsonSerializer.Deserialize<User>(content, options);
        }

        public async Task<User> AddUserAsync(User User)
        {
            var response = await _httpClient.PostAsJsonAsync("api/User", User);
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
            return System.Text.Json.JsonSerializer.Deserialize<User>(content, options);
        }

        public async Task<User> UpdateUserAsync(User User)
        {
            var response = await _httpClient.PutAsJsonAsync($"api/User/{User.UserId}", User);
            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
            return System.Text.Json.JsonSerializer.Deserialize<User>(content, options);
        }

        public async Task<bool> DeleteUserAsync(int id)
        {
            var response = await _httpClient.DeleteAsync($"api/User/{id}");
            return response.IsSuccessStatusCode;
        }

    }
}

6.program.cs
var apiBaseUrl = builder.Configuration["ApiSettings:BaseUrl"];
builder.Services.AddHttpClient<UserApiService>(client =>
{
    client.BaseAddress = new Uri(apiBaseUrl);
});
7.Controllers(folder)
using System.Linq;
using System.Reflection;
using DotWeb.Models;
using DotWeb.Service.UserService;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;

namespace DotWeb.Controllers
{
    public class UserController : Controller
    {
        private readonly UserApiService _userService;
        private readonly IWebHostEnvironment _webHostEnvironment;

        public UserController(UserApiService userService, IWebHostEnvironment webHostEnvironment)
        {
            _userService = userService;
            _webHostEnvironment = webHostEnvironment;
        }

        public async Task<IActionResult> Index()
        {
            var users = await _userService.GetAllUsersAsync();
            return View(users);
        }

        public async Task<IActionResult> Details(int id)
        {
            var user = await _userService.GetUserByIdAsync(id);
            if (user == null)
            {
                return NotFound();
            }
            return View(user);
        }

        public IActionResult Create()
        {
            var model = new UserViewModel
            {
                CountryList = GetCountries(), // Populate countries from your database or an API
                StateList = new List<string>(), // Empty initially, will be populated based on selected country
                CityList = new List<string>() // Empty initially, will be populated based on selected state
            };
            return View(model);
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(UserViewModel user)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    // Allowed file extensions
                    var allowedExtensions = new[] { ".jpg", ".jpeg", ".png" };

                    // Validate file
                    if (user.Photo != null && user.Photo.Length > 0)
                    {
                        var fileExtension = Path.GetExtension(user.Photo.FileName).ToLower();

                        // Check file extension
                        if (!allowedExtensions.Contains(fileExtension))
                        {
                            ModelState.AddModelError("", "Only JPG, JPEG, and PNG files are allowed.");
                            return View(user);
                        }

                        // Check file size (1 KB to 1 MB)
                        if (user.Photo.Length < 1024 || user.Photo.Length > 1048576)
                        {
                            ModelState.AddModelError("", "File size must be between 1 KB and 1 MB.");
                            return View(user);
                        }

                        // Save the file
                        string fileName = Guid.NewGuid().ToString() + Path.GetExtension(user.Photo.FileName);
                        string folder = Path.Combine(_webHostEnvironment.WebRootPath, "images");
                        string filePath = Path.Combine(folder, fileName);

                        // Ensure the directory exists
                        if (!Directory.Exists(folder))
                        {
                            Directory.CreateDirectory(folder);
                        }

                        using (var stream = new FileStream(filePath, FileMode.Create))
                        {
                            await user.Photo.CopyToAsync(stream);
                        }

                        // Create User entity
                        var data = new User()
                        {
                            Name = user.Name,
                            Age = user.Age,
                            Sex = user.Sex,
                            DateOfBirth = user.DateOfBirth,
                            SelfPic = fileName,
                            PasswordHash = user.PasswordHash,
                            Email = user.Email,
                            Mobile = user.Mobile,
                            AadharNumber = user.AadharNumber,
                            PANNumber = user.PANNumber,
                            CurrentAddress = user.CurrentAddress,
                            CorrespondenceAddress = user.CorrespondenceAddress,
                            Country = user.Country,
                            State = user.State,
                            City = user.City,
                            Pincode = user.Pincode
                        };
                        // Add user to the database
                        await _userService.AddUserAsync(data);
                        TempData["Success"] = "User Added Successfully!";
                        // Redirect to the index page
                        return RedirectToAction(nameof(Index));
                    }
                    else
                    {
                        ModelState.AddModelError("", "Profile picture is required.");
                        return View(user);
                    }
                }
                 user.CountryList = GetCountries();  // Re-populate the countries
                user.StateList = (List<string>)GetStates(user.Country); // Re-populate the states based on selected country
                user.CityList = (List<string>)GetCities(user.State); // Re-populate the cities based on selected state

                return View(user);
            }
            catch (Exception ex)
            {
                // Log the exception (if needed) and rethrow or handle appropriately
                ModelState.AddModelError("", "An error occurred while creating the user. Please try again.");
                return View(user);
            }
        }
        [HttpGet]
        public IActionResult GetStates(string countryId)
        {
            if (string.IsNullOrEmpty(countryId))
            {
                return Json(new List<string>());
            }

            var states = GetStatesForCountry(countryId); // Get states based on country
            return Json(states); // Return as JSON to be processed by the client
        }

        [HttpGet]
        public IActionResult GetCities(string stateId)
        {
            if (string.IsNullOrEmpty(stateId))
            {
                return Json(new List<string>());
            }

            var cities = GetCitiesForState(stateId); // Get cities based on state
            return Json(cities); // Return as JSON to be processed by the client
        }

        private List<string> GetCountries()
        {
            // Example: Fetch list of countries from database or an API
            return new List<string> { "India", "USA", "Canada" };
        }

        private List<string> GetStatesForCountry(string countryId)
        {
            // Fetch states based on selected country (from database or API)
            if (countryId == "India")
            {
                return new List<string> { "Delhi", "Maharashtra", "Karnataka" };
            }
            else if (countryId == "USA")
            {
                return new List<string> { "California", "Texas", "Florida" };
            }
            else if (countryId == "Canada")
            {
                return new List<string> { "Ontario", "Quebec", "British Columbia" };
            }
            return new List<string>();
        }

        private List<string> GetCitiesForState(string stateId)
        {
            // Fetch cities based on selected state (from database or API)
            if (stateId == "Delhi")
            {
                return new List<string> { "New Delhi", "Old Delhi" };
            }
            else if (stateId == "California")
            {
                return new List<string> { "Los Angeles", "San Francisco" };
            }
            else if (stateId == "Ontario")
            {
                return new List<string> { "Toronto", "Ottawa" };
            }
            return new List<string>();
        }

        public async Task<IActionResult> Edit(int id)
        {
            var user = await _userService.GetUserByIdAsync(id);
            if (user == null)
            {
                return NotFound();
            }
            return View(user);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(User user, IFormFile profilePicture)
        {
            if (ModelState.IsValid)
            {
                // Check if a new profile picture is uploaded
                if (profilePicture != null && profilePicture.Length > 0)
                {
                    // Validate file extension
                    var allowedExtensions = new[] { ".jpg", ".jpeg", ".png" };
                    var fileExtension = Path.GetExtension(profilePicture.FileName).ToLower();

                    if (!allowedExtensions.Contains(fileExtension))
                    {
                        ModelState.AddModelError("", "Only JPG, JPEG, and PNG files are allowed.");
                        return View(user); // Return the view with error
                    }

                    // Validate file size (1 KB to 1 MB)
                    if (profilePicture.Length < 1024 || profilePicture.Length > 1048576)
                    {
                        ModelState.AddModelError("", "File size must be between 1 KB and 1 MB.");
                        return View(user); // Return the view with error
                    }

                    // Ensure the uploads directory exists
                    var uploadDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads");
                    if (!Directory.Exists(uploadDirectory))
                    {
                        Directory.CreateDirectory(uploadDirectory);
                    }

                    // Delete the old file
                    if (!string.IsNullOrEmpty(user.SelfPic))
                    {
                        var oldFilePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", user.SelfPic);
                        if (System.IO.File.Exists(oldFilePath))
                        {
                            System.IO.File.Delete(oldFilePath);
                        }
                    }

                    // Save the new profile picture
                    var fileName = Guid.NewGuid().ToString() + fileExtension;
                    var filePath = Path.Combine(uploadDirectory, fileName);

                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await profilePicture.CopyToAsync(stream);
                    }

                    // Update the user with the new file path
                    user.SelfPic = Path.Combine("uploads", fileName); // Save relative path
                }

                // Update the user details (including the profile picture path if updated)
                await _userService.UpdateUserAsync(user);

                return RedirectToAction(nameof(Index)); // Redirect after successful update
            }

            return View(user); // Return the view with validation errors if ModelState is invalid
        }

        public async Task<IActionResult> Delete(int id)
        {
            var user = await _userService.GetUserByIdAsync(id);
            if (user == null)
            {
                return NotFound();
            }
            return View(user);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            await _userService.DeleteUserAsync(id);
            return RedirectToAction(nameof(Index));
        }
    }
}

How to Create Crud app using asp.net core Web Api thru Db First approach or reverse engineering How to Create Crud app using asp.net core Web Api thru Db First approach or reverse engineering Reviewed by Rikesh on December 02, 2024 Rating: 5

No comments:

Powered by Blogger.