European ASP.NET MVC 4 and MVC 5 Hosting

BLOG about ASP.NET MVC 3, ASP.NET MVC 4, and ASP.NET MVC 5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

ASP.NET MVC Hosting - HostForLIFE.eu :: Bootstrap Modal PopUp Using ASP.NET MVC

clock June 20, 2025 08:20 by author Peter

We can show and hide the modal using the methods provided by Bootstrap Modal plugin.


Description
We are using modal ('show') and modal ('hide') methods to show and hide the login modal.

Reference
Before this article you should go through my Introduction to Bootstrap. Show Bootstrap Image Using Asp.Net MVC http://www.c-sharpcorner.com/blogs/bootstrap-image-show-using-asp-net-mvc3

Steps
Create a controller class file called "HomeController.cs" and add controller action method called "ModalPopUp()";
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
  
namespace PeterMVCBootstrapImages.Controllers  
{  
    public class HomeController : Controller  
    {  
        //  
        // GET: /Home/  
  
        public ActionResult Index()  
        {  
            return View();  
        }  
  
        public ActionResult ModalPopUp()  
        {  
            return View();  
        }  
  
    }  


Then create a view file named "ModalPopUp.cshtml".
@{  
    ViewBag.Title = "
Peter Bootstrap PopUp";  
}  
  
<title>@ViewBag.Title</title>  
  
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">  
  
<style>  
    .button {  
        background-color: #4CAF50; /* Green */  
        border: none;  
        color: white;  
        padding: 15px 32px;  
        text-align: center;  
        text-decoration: none;  
        display: inline-block;  
        font-size: 16px;  
        margin: 4px 2px;  
        cursor: pointer;  
    }  
  
    .button1 {  
        border-radius: 2px;  
    }  
  
    .button2 {  
        border-radius: 4px;  
    }  
  
    .button3 {  
        border-radius: 8px;  
    }  
  
    .button4 {  
        border-radius: 12px;  
    }  
  
    .button5 {  
        border-radius: 50%;  
    }  
</style>  
<div>  
    <h2 style="background-color: Yellow;color: Blue; text-align: center; font-style: oblique">
Peter Bootstrap PopUp</h2>  
    <fieldset>  
        <legend style="color:orangered">Click On 
Peter Bootstrap PopUp</legend>  
        <div class="container">  
            <div class="row">  
                <div class="col-xs-12">  
  
                    <button id="btnShowModal" type="button"  
                            class="btn btn-sm btn-default pull-left col-lg-11 button button4">  
                        
Peter Modals  
                    </button>  
  
                    <div class="modal fade" tabindex="-1" id="loginModal"  
                         data-keyboard="false" data-backdrop="static">  
                        <div class="modal-dialog modal-lg">  
                            <div class="modal-content">  
                                <div class="modal-header">  
                                    <button type="button" class="close" data-dismiss="modal">  
                                        ×  
                                    </button>  
                                    <h4 class="modal-title">
Peter Login</h4>  
                                </div>  
                                <div class="modal-body">  
                                    <form>  
                                        <div class="form-group">  
                                            <input class="form-control" type="text"  
                                                   placeholder="Login Username" id="inputUserName" />  
                                        </div>  
                                        <div class="form-group">  
                                            <input class="form-control" placeholder="Login Password"  
                                                   type="password" id="inputPassword" />  
                                        </div>  
                                    </form>  
                                </div>  
                                <div class="modal-footer">  
                                    <button type="submit" class="btn btn-primary button button4">Sign</button>  
                                    <button type="button" id="btnHideModal" class="btn btn-primary button button4">  
                                        Hide  
                                    </button>  
                                </div>  
                            </div>  
                        </div>  
                    </div>  
  
                </div>  
            </div>  
        </div>  
    </fieldset>  
</div>  
    <footer>  
        <p style="background-color: Yellow; font-weight: bold; color:blue; text-align: center; font-style: oblique">  
            ©  
            <script> document.write(new Date().toDateString()); </script>  
        </p>  
    </footer>  
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">  
    </script>  
    <script src="bootstrap/js/bootstrap.min.js"></script>  
  
    <script type="text/javascript">  
        $(document).ready(function () {  
            $("#btnShowModal").click(function () {  
                $("#loginModal").modal('show');  
            });  
  
            $("#btnHideModal").click(function () {  
                $("#loginModal").modal('hide');  
            });  
        });  
    </script> 

Here all reference files like bootstrap.min.css and jquery.min.js and bootstrap.min.js should be added to
add bootstrap features.
 
I have added code for a button to perform modal popup.
<button id="btnShowModal" type="button"  
       class="btn btn-sm btn-default pull-left col-lg-11 button button4">  
   
Peter Modals  
</button> 

I have added code for the modal form to appear in a fade style.
<div class="modal fade" tabindex="-1" id="loginModal"  
     data-keyboard="false" data-backdrop="static"> 
   

Here is the code for size of the modal.
<div class="modal-dialog modal-lg"> 

Controls are added Inside Modal content such as  header text , buttons, cross symbol button, text boxes and related control properties:
<div class="modal-content">  
    <div class="modal-header">  
        <button type="button" class="close" data-dismiss="modal">  
            ×  
        </button>  
        <h4 class="modal-title">
Peter Login</h4>  
    </div>  
    <div class="modal-body">  
        <form>  
            <div class="form-group">  
                <input class="form-control" type="text"  
                       placeholder="Login Username" id="inputUserName" />  
            </div>  
            <div class="form-group">  
                <input class="form-control" placeholder="Login Password"  
                       type="password" id="inputPassword" />  
            </div>  
        </form>  
    </div>  
    <div class="modal-footer">  
        <button type="submit" class="btn btn-primary button button4">Sign</button>  
        <button type="button" id="btnHideModal" class="btn btn-primary button button4">  
            Hide  
        </button>  
    </div>  
</div> 

For cross symbol button in header part.
<button type="button" class="close" data-dismiss="modal">  
    ×  
</button> 

For Header part.
<div class="modal-header">  
   <button type="button" class="close" data-dismiss="modal">  
       ×  
   </button>  
   <h4 class="modal-title">
Peter Login</h4>  
</div> 

For textBoxes

<div class="modal-body">  
    <form>  
        <div class="form-group">  
            <input class="form-control" type="text"  
                   placeholder="Login Username" id="inputUserName" />  
        </div>  
        <div class="form-group">  
            <input class="form-control" placeholder="Login Password"  
                   type="password" id="inputPassword" />  
        </div>  
    </form>  
</div> 


For footer part.
<div class="modal-footer">  
    <button type="submit" class="btn btn-primary button button4">Sign</button>  
    <button type="button" id="btnHideModal" class="btn btn-primary button button4">  
        Hide  
    </button>  
</div> 

Here I added one javascript and added button id such as btnShowModal and btnHideModal to show and hide modal.

<script type="text/javascript">  
    $(document).ready(function () {  
        $("#btnShowModal").click(function () {  
            $("#loginModal").modal('show');  
        });  

        $("#btnHideModal").click(function () {  
            $("#loginModal").modal('hide');  
        });  
    });  
</script> 


Here I added css style to add style in buttons.
<style>  
    .button {  
        background-color: #4CAF50; /* Green */  
        border: none;  
        color: white;  
        padding: 15px 32px;  
        text-align: center;  
        text-decoration: none;  
        display: inline-block;  
        font-size: 16px;  
        margin: 4px 2px;  
        cursor: pointer;  
    }  
  
    .button1 {  
        border-radius: 2px;  
    }  
  
    .button2 {  
        border-radius: 4px;  
    }  
  
    .button3 {  
        border-radius: 8px;  
    }  
  
    .button4 {  
        border-radius: 12px;  
    }  
  
    .button5 {  
        border-radius: 50%;  
    }  
</style>   




ASP.NET MVC Hosting - HostForLIFE.eu :: Controllers in MVC: An Introduction

clock June 12, 2025 09:06 by author Peter

This article provides an overview of the Controller in MVC. As you know, MVC stands for Model , View and Controller; so, Controller plays a very important role in MVC. We'll learn the controller actions and action results in here and how the controllers are used to interact with the MVC applications.

Overview
The controller in MVC is responsible for responding the request made against the ASP.NET MVC Web Application. Each browser request is mapped to a specific controller that is defined in the MVC application.

Suppose you are entering the following URL in the browser:
http://localhost:1234/Sample

It means that the Controller is called SampleController. The browser is making a request to the controller so now the SampleController is responsible for providing the response to the browser. It might be possible that the controller returns a specific view back to the browser or the controller might redirect the user to another controller.

Getting Started
Let us create a Controller in a MVC application. To create a controller you must have the MVC application so at first we'll create the MVC application and then controller. Just follow the procedure below.

Step 1: Create an ASP.NET Web Application and enter the name as in the following:

Step 2: Select MVC Project Template in the One ASP.NET Wizard.

Step 3: In the Solution Explorer, right-click on the Controllers folder then click on "Add" -> "Controller...".

Step 4: Now select the MVC Empty Controller.

And enter the name as Sample as in the following:


After entering the controller name, using scaffolding there is a folder named Sample (the same name as the newly added controller) will be added automatically in the Views folder. Have a look:


Step 5: You can see the newly added controller has code as in the following:
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Web;  
    using System.Web.Mvc;  
    namespace DemoMvc.Controllers  
    {  
        public class SampleController : Controller  
        {  
            // GET: Sample  
            public ActionResult Index()  
            {  
                return View();  
            }  
        }  
    } 

In the code above, you can see that the controller is created in the form of a class so you can say that it is just a class that is derived from the Controller class. This class inherits the Controller class (base class). In the next section, we'll understand the actions.

Overview of Actions in Controller

The actions are disclosed by the controller. An action is a method on a controller that is called when you enter a specific URL in the browser. Suppose you enter the following URL in the browser:
http://localhost:1234/Sample/Index

The Index() method is called through the preceding URL. This Index() method is stored in the SampleController. It is necessary that the access modifier of the action method must be public. This action method of any controller cannot be overloaded further and also cannot be a static method.

Overview of Action Results
As you can see in the preceding action method that the return type of that Index() action method is ActionResult, so an action method returns an action result. An action result is what a controller action returns in response to a browser request.

There are various types of action results supported in the MVC, as given below:

  • ViewResult: Represents HTML and markup.
  • EmptyResult: No Result
  • RedirectResult: a redirection to a new URL
  • JsonResult: a JSON result that is used in ajax app
  • JavaScriptResult: a JavaScript result
  • ContentResult: a text result

In most cases the controller action returns a ViewResult as in the following:
    public class SampleController : Controller  
    {  
        // GET: Sample  
        public ActionResult Index()  
        {  
            return View();  
        }  
    } 


You can see in the code above that the View is used to return a ViewResult. When this is returned, HTML is returned to the browser. You can see the methods of the controller base class:

  • View: Returns a ViewResult action result.
  • Redirect: Returns a RedirectResult
  • JSON: Returns a JsonResult
  • JavaScript: Returns a JavaScriptResult
  • RedirectToAction: Returns a RedirectToActionResult

So, suppose you want to redirect from one controller to another controller, you need to use the RedirectToAction() method. Have a look:
    using System.Web.Mvc;  
    namespace DemoMvc.Controllers  
    {  
        public class SampleController : Controller  
        {  
            // GET: Sample  
            public ActionResult Index()  
            {  
                return View();  
            }  
            public ActionResult SampleWorld()  
            {  
                return RedirectToAction("Welcome");  
            }  
            public ActionResult Welcome()  
            {  
                return View();  
            }  
        }  
    } 

Suppose we want to use the ContentResult action result because it is special. It returns an action result as simple plain text. Have a look:

    using System.Web.Mvc;  
    namespace DemoMvc.Controllers  
    {  
        public class SampleController : Controller  
        {  
            // GET: Sample  
            public ActionResult Index()  
            {  
                return View();  
            }  
            public ActionResult Welcome()  
            {  
                return Content("Hello and Welcome to MVC");  
            }  
        }  
    } 


Adding View
You can add a view for every controller in a very easy way. Have a look at the following procedure.

Step 1: Just right-click on the controller and select Add View

Step 2: Just click on Add in the next wizard

 

Step 3: When you run the Welcome View, you can see the following screenshot

You can check out in the browser URL that the Welcome controller action method is called of the SampleController. That's it.

Summary
This article provided an overview of the controller, controller actions and action results of ASP.NET MVC. In here you learned the overview of controllers, next we'll learn the custom routes in controllers. Thanks for reading



ASP.NET MVC Hosting - HostForLIFE.eu :: Use the Dapper and Repository Patterns to Create a CRUD Application in.NET 8 MVC

clock May 7, 2025 09:33 by author Peter

Creating a CRUD (Create, Read, Update, Delete) application is a core skill for any .NET developer. In this guide, we'll show you how to build a CRUD app using ASP.NET Core MVC (.NET 8), Dapper ORM, and the Repository Pattern. This approach is fast, easy to maintain, and great for building real-world applications.


Building an ASP.NET MVC project using Dapper Micro ORM and .NET 8.0 involves 10 key steps. Here's a simple breakdown to help you set up the project effectively.

  • Create a New ASP.NET Core MVC Project
  • Install Dapper and Microsoft.Data.SqlClient Packages
  • Set Up SQL Server Database and Table
  • Configure Database Connection
  • Create the model
  • Create a DBContext Folder inside the folder create the DapperContext.cs file
  • Create a Repository Folder inside the folder create IStudentRepo.cs and StudentRepo.cs file
  • Configure Dependency Injection
  • Create Controller
  • Create Views

Continue following the steps mentioned above.

Step 1. Create a New ASP.NET Core MVC Project.

Choose the MVC project template.

Configure your new project by giving it a meaningful name and selecting the folder where it should be created.

No changes are needed in the Additional Information section.

The project window appears as shown in the image below.

Step 2. Install Dapper and Microsoft.Data.SqlClient Packages. Navigate to Tools > NuGet Package Manager > Manage NuGet Packages for Solution.

Go to the Browse tab, search for Dapper, and select the first package that appears. Check the box next to your project name, ensure the latest version is selected (update it if not), and then click Install.

Go to the Browse tab, and search for Microsoft.Data.SqlClient, and select the first package that appears. Tick the checkbox next to your project name, make sure the latest version is selected (update if necessary), and then click Install.

Click Accept to agree to the license terms and proceed with the installation.


Open Solution Explorer, navigate to Dependencies > Packages and verify that both installed packages are listed. This confirms they were successfully added to your project.


Step 3. Set Up SQL Server Database and Table
Open SQL Server Management Studio (SSMS), then launch a New Query window. Use the following query to create a new database and table.
--Create a database StudentDB.
CREATE DATABASE StudentDB;
Use StudentDB;

--Create a table Students with fields: ID, Name, Age, Email.
CREATE TABLE Student(
               ID int primary key identity(1,1),
               Name varchar(50),
               Age int,
               Email varchar(50)
);

Step 4. Configure Database Connection
Add the connection string to the appsettings.json file, ensuring that the entries are separated by commas (,).


"ConnectionStrings": {
    "DefaultConnection": "Server=LAPTOP-TD1MGGBL;Database=StudentDB;Trusted_Connection=True;TrustServerCertificate=True;"
}


Step 5. Create the model
Right-click on the Models folder, select Add > Class and name it Student.cs. After creating the class, add the following code.


File: Student.cs
namespace CURD_Demo.Models
{
    public class Student
    {
        public int Id { get; set; }
        public required string Name { get; set; }
        public int Age { get; set; }
        public required string Email { get; set; }
    }
}


Step 6. Create a DBContext Folder inside the folder ADD DapperContext.cs file.
Right-click on the project name in Solution Explorer, then go to Add > New Folder and name it DBContext. Inside the DBContext folder, add a class named DapperContext.cs and include the following code inside the file.

 

File: DappContext.cs
using Microsoft.Data.SqlClient;
using System.Data;

namespace CURD_Demo.DBContext
{
    public class DapperContext
    {
        private readonly IConfiguration _configuration;
        private readonly string? _connectionString;
        public DapperContext(IConfiguration configuration)
        {
            _configuration = configuration;
            _connectionString = _configuration.GetConnectionString("DefaultConnection");
        }
        public IDbConnection CreateConnection() => new SqlConnection(_connectionString);
    }
}


Step 7. Create a Repository Folder inside the folder then create IStudentRepo.cs and StudentRepo.cs files.
Right-click on the project name in Solution Explorer, then go to Add > New Folder and name it Repository. Inside the Repository folder, add an interface named IStudentRepo.cs and a class named StudentRepo.cs. After creating these files, add the following code inside each file.


File: IStudentRepo.cs
using CURD_Demo.Models;

namespace CURD_Demo.Repository
{
    public interface IStudentRepo
    {
        IEnumerable<Student> GetAll();
        Student? GetById(int id);
        void Add(Student student);
        void Update(Student student);
        void Delete(int id);
    }
}


File: StudentRepo.cs
using CURD_Demo.Models;
using CURD_Demo.DBContext;
using Dapper;
namespace CURD_Demo.Repository
{
    public class StudentRepo : IStudentRepo
    {
        private readonly DapperContext _context;
        public StudentRepo(DapperContext context)
        {
            _context = context;
        }
        public IEnumerable<Student> GetAll()
        {
            using (var connection = _context.CreateConnection())
            {
                var sql = "SELECT * FROM Student";
                return connection.Query<Student>(sql);
            }
        }
        public Student? GetById(int id)
        {
            using (var connection = _context.CreateConnection())
            {
                var sql = "SELECT * FROM Student WHERE Id = @Id";
                return connection.QuerySingleOrDefault<Student>(sql, new { Id = id });
            }
        }
        public void Add(Student student)
        {
            using (var connection = _context.CreateConnection())
            {
                var sql = "INSERT INTO Student (Name, Age, Email) VALUES (@Name, @Age, @Email)";
                connection.Execute(sql, student);
            }
        }
        public void Update(Student student)
        {
            using (var connection = _context.CreateConnection())
            {
                var sql = "UPDATE Student SET Name = @Name, Age = @Age, Email = @Email WHERE Id = @Id";
                connection.Execute(sql, student);
            }
        }
        public void Delete(int id)
        {
            using (var connection = _context.CreateConnection())
            {
                var sql = "DELETE FROM Student WHERE Id = @Id";
                connection.Execute(sql, new { Id = id });
            }
        }
    }
}


Step 8. Configure Dependency Injection
Open the Program.cs file and add the necessary dependencies for Dapper and the repositories using the following code.


File: Program.cs
//Configure Dependency Injection

builder.Services.AddSingleton<CURD_Demo.DBContext.DapperContext>();
builder.Services.AddScoped<CURD_Demo.Repository.IStudentRepo, CURD_Demo.Repository.StudentRepo>();


Step 9. Create Controller
Right-click on the Controllers folder, select Add > Controller, then choose MVC Controller - Empty and click Add. In the pop-up window, enter StudentController as the controller name and click Add. This will create StudentController inside the Controllers folder. Then, add the following code to the StudentController.cs file.

 

File: StudentController.cs
using CURD_Demo.Models;
using Microsoft.AspNetCore.Mvc;
using CURD_Demo.Repository;

namespace CURD_Demo.Controllers
{
    public class StudentController : Controller
    {
        private readonly IStudentRepo _studentRepo;
        public StudentController(IStudentRepo studentRepo)
        {
            _studentRepo = studentRepo;
        }
        public IActionResult Student()
        {
            var students = _studentRepo.GetAll();
            return View(students);
        }
        public IActionResult Details(int id)
        {
            var student = _studentRepo.GetById(id);
            if (student == null)
            {
                return NotFound();
            }
            return View(student);
        }
        public IActionResult Create()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Student student)
        {
            if (ModelState.IsValid)
            {
                _studentRepo.Add(student);
                return RedirectToAction(nameof(Student));
            }
            return View(student);
        }
        public IActionResult Edit(int id)
        {
            var student = _studentRepo.GetById(id);
            if (student == null)
            {
                return NotFound();
            }
            return View(student);
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Edit(Student student)
        {
            if (ModelState.IsValid)
            {
                _studentRepo.Update(student);
                return RedirectToAction(nameof(Student));
            }
            return View(student);
        }
        public IActionResult Delete(int id)
        {
            var student = _studentRepo.GetById(id);
            if (student == null)
            {
                return NotFound();
            }
            return View(student);
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult DeleteConfirmed(int id)
        {
            _studentRepo.Delete(id);
            return RedirectToAction(nameof(Student));
        }
    }
}


Step 10. Create Views
Right-click on the Views folder, navigate to Add > New Item, select Razor View - Empty, and click Add. In the pop-up window, enter Student.cshtml as the name and click Add. This will create a Student.cshtml file inside the View/Student folder. Then, add the following code inside the Student.cshtml file.

 

File: Student.cshtml
@model IEnumerable<CURD_Demo.Models.Student>
@{
    ViewData["Title"] = "Students";
}

<h2>Student List</h2>

<div>
    <a asp-action="Create" class="btn btn-primary">Add New Student</a>
</div>
<table class="table table-bordered">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Email)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Age)
            </th>
            <th>
                Actions
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var student in Model)
        {
            <tr>
                <td>
                    @{
                        @student.Name
                    }
                </td>
                <td>
                    @{
                        @student.Email
                    }
                </td>
                <td>
                    @{
                        @student.Age
                    }
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@student.Id">Edit</a> |
                    <a asp-action="Delete" asp-route-id="@student.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Right-click on the Student folder, navigate to Add > New Item, select Razor View - Empty, and click Add. In the pop-up window, enter Create.cshtml as the name and click Add. This will create a Create.cshtml file inside the Student folder. Then, add the following code inside the Create.cshtml file.

File: Create.cshtml

@model CURD_Demo.Models.Student
@{
    ViewData["Title"] = "Create Student";
}

<h2>Add Student</h2>
<form asp-action="Create" method="post">
    <div class="form-group">
        <label for="Name" class="form-label"></label>
        <input name="Name" placeholder="Enter Your Name" class="form-control" />
        <span class="text-danger"></span>
    </div>
    <div class="form-group">
        <label for="Email" class="control-label"></label>
        <input name="Email" placeholder="Enter Your Email" class="form-control" />
        <span class="text-danger"></span>
    </div>
    <div class="form-group">
        <label for="Age" class="control-label"></label>
        <input name="Age" placeholder="Enter Your Age" class="form-control" />
        <span class="text-danger"></span>
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
    <a asp-action="Student">Back</a>
</form>


Right-click on the Student folder, navigate to Add > New Item, select Razor View - Empty, and click Add. In the pop-up window, enter Edit.cshtml as the name and click Add. This will create a Edit.cshtml file inside the Student folder. Then, add the following code inside the Edit.cshtml file.

File: Edit.cshtml
@model CURD_Demo.Models.Student
@{
    ViewData["Title"] = "Edit";
}

<h2>EditStudent</h2>
<form asp-action="Edit" metod="post">
    <input type="hidden" asp-for="Id" />
    <div class="form-group">
        <label asp-for="Name" class="form-label"></label>
        <input asp-for="Name" placeholder="Enter Your Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Email" class="form-label"></label>
        <input asp-for="Email" placeholder="Enter Your Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Age" class="form-label"></label>
        <input asp-for="Age" placeholder="Enter Your Age" class="form-control" />
        <span asp-validation-for="Age" class="text-danger"></span>
    </div>
    <button type="submit" class="btn btn-primary">Update</button>
</form>

Right-click on the Student folder, navigate to Add > New Item, select Razor View - Empty, and click Add. In the pop-up window, enter Delete.cshtml as the name and click Add. This will create a Delete.cshtml file inside the Student folder. Then, add the following code inside the Delete.cshtml file.

File: Delete.cshtml
@model CURD_Demo.Models.Student
@{
    ViewData["Title"] = "Delete";
}

<h2>Delete Student</h2>
<div>
    <h4>Are you sure you want to delete this Student?</h4>
    <div>
        <p>Name: @Model.Name</p>
        <p>Email: @Model.Email</p>
        <p>Age: @Model.Age</p>
    </div>
</div>

<form method="post" asp-action="DeleteConfirmed">
    <input type="hidden" asp-for="Id" />
    <div class="form-group">
        <button type="submit" class="btn btn-danger">Delete</button>
        <a asp-action="Index" class="btn btn-secondary">Cancel</a>
    </div>
</form>

Conclusion

In this article, we walked through the process of building a complete CRUD application using ASP.NET Core MVC (.NET 8), Dapper ORM, and the Repository Pattern. By combining the simplicity and performance of Dapper with a clean architecture approach, you’ve created a project that is both efficient and easy to maintain. This setup is ideal for small to medium-sized applications where performance matters and development speed is important. Whether you're a beginner exploring .NET or a developer looking to use lightweight tools over heavy ORMs, this project serves as a solid foundation for real-world applications.

Thank you for taking the time to read this article! I hope it helped you understand how to build a CRUD application using ASP.NET Core MVC, Dapper ORM, and the Repository Pattern. If you found this guide helpful, feel free to share it with others or leave your feedback.

Happy coding!



ASP.NET MVC Hosting - HostForLIFE.eu :: Building a User Subscription Module in ASP.NET MVC with C# 14

clock April 29, 2025 10:00 by author Peter

In modern web applications, subscription-based features are essential for managing user access, monetizing content, or offering tiered services. In this guide, we will build a comprehensive User Subscription Module using ASP.NET MVC (Model-View-Controller) and C# 14. The module will support:

  • User registration and login
  • Subscription plan selection
  • Payment integration (mocked)
  • Role-based access based on subscription level
  • Subscription management (upgrade/downgrade/cancel)

We’ll also take advantage of new C# 14 features such as primary constructors, collection expressions, field-backed properties, and extension members to make our code more concise and modern. These features help streamline the codebase and make it easier to read and maintain, especially in large applications with many interrelated components.

By the end of this tutorial, you'll have a functioning module that you can integrate into an existing ASP.NET MVC project. Whether you're building a SaaS platform or a content subscription service, the patterns and practices here will provide a strong foundation for building reliable, scalable subscription systems.

1. Project Setup
The first step in developing our subscription module is to use Visual Studio to create a new ASP.NET MVC application. Our data models, business logic, and user interface elements will be constructed upon this basis. Select the MVC template and set up your authentication preferences according to your user base's requirements when prompted during project creation. In order to enable Entity Framework and ASP.NET Identity, which are essential to our user and subscription management features, we must install a few NuGet packages after building the project. Microsoft, for instance. We may construct our database access layer and Microsoft.AspNet.Identity using EntityFramework. EntityFramework offers the ability to authenticate users.

Install-Package Microsoft.EntityFramework -Version 6.4.4
Install-Package Microsoft.AspNet.Identity.EntityFramework
Install-Package Stripe.net // Optional for real payment integration

These packages lay the groundwork for our entire system. With Entity Framework, we can interact with the database using strongly typed models, and Identity gives us a comprehensive system for managing users and roles. The Stripe package is optional but included for future scalability and integration.

Using NuGet simplifies the setup process and ensures that you get the latest, most secure versions of each dependency. This modular approach also makes the project easier to maintain, since each package can be updated independently of the others.

2. Define Models

To store and manage subscription data, we need to define our data models. These include SubscriptionPlan for defining available plans, UserSubscription to represent a user’s active or past subscriptions, and ApplicationUser which extends ASP.NET Identity’s user model. Each of these models plays a key role in organizing how data is stored and retrieved.

public class SubscriptionPlan
{
    public int Id { get; set; }

    public string Name
    {
        get => field;
        set => field = value ?? throw new ArgumentNullException(nameof(value));
    }

    public decimal Price { get; set; }
    public string Description { get; set; }
    public int DurationInDays { get; set; }
}

public class UserSubscription
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public int PlanId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public bool IsActive => DateTime.UtcNow <= EndDate;

    public virtual ApplicationUser User { get; set; }
    public virtual SubscriptionPlan Plan { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<UserSubscription> Subscriptions { get; set; }
}

These classes map to tables in our SQL database and help organize our business logic. The use of navigation properties (virtual) allows us to navigate related entities easily when using Entity Framework. The UserSubscription model is especially critical for tracking start and end dates, which will be used to determine access.

In C# 14, field-backed properties like Name in SubscriptionPlan help ensure data integrity with built-in validation. This allows us to enforce rules such as requiring names to be non-null directly in the model, rather than repeating this logic throughout the codebase.

3. Add Subscription Logic to DbContext

Next, we extend our DbContext to include our new models. This allows us to use EF to manage our tables and data.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<SubscriptionPlan> SubscriptionPlans { get; set; }
    public DbSet<UserSubscription> UserSubscriptions { get; set; }

    public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { }

    public static ApplicationDbContext Create() => new();
}

This DbContext class bridges your application to the database. Entity Framework uses it to perform CRUD operations and generate SQL queries under the hood. The DbSet<T> properties tell EF which entities should be tracked and mapped to database tables.

The constructor and factory method (Create) show how to simplify context initialization, and using the latest syntax from C# 14 makes it even more concise. Keeping the context clean and modular helps when unit testing or transitioning to more advanced patterns like repository or unit-of-work.

4. Seed Subscription Plans
Add seed data to initialize plans in development or production environments.

context.SubscriptionPlans.AddOrUpdate(p => p.Name,
    new SubscriptionPlan { Name = "Free", Price = 0, Description = "Basic access", DurationInDays = 30 },
    new SubscriptionPlan { Name = "Pro", Price = 9.99M, Description = "Pro features", DurationInDays = 30 },
    new SubscriptionPlan { Name = "Enterprise", Price = 29.99M, Description = "All features", DurationInDays = 90 }
);

Seeding is essential to provide default options without requiring manual input every time the database is recreated. This is useful not only in development but also in CI/CD pipelines for automated deployments. These plans can be adjusted or extended later to suit business needs.

This code ensures that users always have valid plans to choose from. It's especially useful when the app is first launched, ensuring a smooth experience from the very first interaction.
5. Controllers and Views
Here’s a controller that uses a primary constructor:
[Authorize]
public class SubscriptionController(ApplicationDbContext db) : Controller
{
    public ActionResult Index() => View(db.SubscriptionPlans.ToList());

    public ActionResult Subscribe(int id) => View(db.SubscriptionPlans.Find(id));

    [HttpPost]
    public ActionResult SubscribeConfirmed(int id)
    {
        var userId = User.Identity.GetUserId();
        var plan = db.SubscriptionPlans.Find(id);

        var subscription = new UserSubscription
        {
            UserId = userId,
            PlanId = plan.Id,
            StartDate = DateTime.UtcNow,
            EndDate = DateTime.UtcNow.AddDays(plan.DurationInDays)
        };

        db.UserSubscriptions.Add(subscription);
        db.SaveChanges();

        return RedirectToAction("MySubscription");
    }

    public ActionResult MySubscription()
    {
        var userId = User.Identity.GetUserId();
        var activeSub = db.UserSubscriptions
            .Include("Plan")
            .Where(s => s.UserId == userId && s.IsActive)
            .OrderByDescending(s => s.EndDate)
            .FirstOrDefault();

        return View(activeSub);
    }
}


This controller manages the user's interaction with subscription plans. It retrieves available plans, handles subscription actions, and displays the user's current subscription. Using C# 14 primary constructors simplifies dependency injection, especially when there are few dependencies.

The controller is tied to Identity for user management, ensuring that actions like subscribing are tied to the correct user context. This integration of business logic and authentication is central to secure and personalized application flows.

6. Access Control Based on Subscription

Create a custom authorization attribute:
public class SubscriptionAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var userId = httpContext.User.Identity.GetUserId();
        var db = new ApplicationDbContext();
        var sub = db.UserSubscriptions.FirstOrDefault(x => x.UserId == userId && x.EndDate >= DateTime.UtcNow);
        return sub != null;
    }
}


Use it like this:
[SubscriptionAuthorize]
public ActionResult PremiumContent()
{
    return View();
}


This custom attribute checks if the logged-in user has an active subscription. It’s a lightweight and reusable solution to protect controller actions or entire controllers. It works well for scenarios where only subscribers should access certain parts of the application.

By encapsulating this logic into an attribute, we keep our controller actions clean and focused on what they need to do, rather than how authorization should be enforced. This improves both readability and maintainability.

7. Optional: Mock Payment Service

Handling payments is a critical part of any subscription system, but during development or for MVP testing, it's useful to mock this functionality. A mock payment service allows us to simulate successful transactions without integrating a third-party provider like Stripe or PayPal.

Below is a simple mock PaymentService class. It returns true to simulate a successful payment transaction, regardless of input. This allows you to develop and test your system logic without incurring real charges or managing payment API credentials.
public class PaymentService
{
    public bool ChargeUser(string userId, decimal amount)
    {
        // Simulate a successful payment
        Console.WriteLine($"Charging user {userId} for ${amount}");
        return true;
    }
}


You can integrate this into your subscription flow by calling it before saving the subscription. For example:
var paymentService = new PaymentService();
if (paymentService.ChargeUser(userId, plan.Price))
{
    var subscription = new UserSubscription
    {
        UserId = userId,
        PlanId = plan.Id,
        StartDate = DateTime.UtcNow,
        EndDate = DateTime.UtcNow.AddDays(plan.DurationInDays)
    };

    db.UserSubscriptions.Add(subscription);
    db.SaveChanges();
}

Using a mock now allows you to fully test your end-to-end subscription logic while making it simple to switch to a real provider later. When you're ready for live payments, just replace it PaymentService with a real implementation that connects to your gateway of choice.

8. Extension Members in C# 14

Use extension members to clean check the premium status:
public static class SubscriptionExtensions
{
    extension(UserSubscription subscription)
    {
        public bool IsPremium => ["Pro", "Enterprise"].Contains(subscription.Plan?.Name);
    }
}


Then in your code:

if (userSubscription.IsPremium)
{
    // Show premium features
}

Extension members let you encapsulate logic related to a class without modifying the class itself. This is ideal for computed properties like determining plan tier. It keeps your domain model lean while making your code more expressive. This feature is especially useful in scenarios where your business logic spans multiple types or you need utility-style operations across many parts of the app. You avoid cluttering your core model with too much logic.

9. Views

Here's a simple Index.cshtml:
@model IEnumerable<SubscriptionPlan>
<h2>Choose a Plan</h2>
@foreach (var plan in Model)
{
    <div>
        <h3>@plan.Name</h3>
        <p>@plan.Description</p>
        <p>Price: [email protected]</p>
        @Html.ActionLink("Subscribe", "Subscribe", new { id = plan.Id })
    </div>
}

This view lists all available subscription plans. Each plan includes a button that links to the subscribe confirmation page. The use of Razor syntax makes it easy to iterate through models and generate dynamic HTML. Views like this help users quickly understand the value proposition of each plan. With Bootstrap or Tailwind CSS, you could further enhance the design for a polished, responsive experience.

Conclusion

We built a user subscription module using ASP.NET MVC and C# 14, leveraging modern language features for better performance and readability. We explored models, controllers, access control, extension methods, and mocked payment processing. This provides a solid foundation for a SaaS or subscription-based application. Next steps might include adding webhook support, real payment integration (e.g., Square, Stripe), user dashboards, or analytics.



ASP.NET MVC Hosting - HostForLIFE.eu :: How to Use View Files to Publish ASP.NET Core MVC Project.NET 8?

clock April 15, 2025 07:29 by author Peter

This walkthrough will address the following questions and teach you how to publish CSHTML files along with the project.

  • How to create an Asp.Net Core MVC Project?
  • What are the settings for the Project file to publish the CSHTML file while publishing?
  • What are the settings to be done on the publish screen or wizards before publishing?

We are using Visual Studio 2022 for this walk-through.


How to create an ASP.NET Core MVC Project?

Select ASP.NET Core web App (Model-View-Controller as per IMAGE1.

Set the following things in the above image 2:

  • Project name: Set your project name: AspNetMvcNet8Proj.
  • Location: Set your location by clicking… or select previous by clicking on the dropdown list.

  • Framework: Select your .NET version (6.0, 8.0. . .)

We selected .NET 8

  • Authentication Type: None
  • (You can select as per your requirement – None, Individual Accounts, Microsoft Identity Platform, or Windows)
  • Configure for HTTPS: Set Configure for HTTPS for secure request and response.
  • Enable Container Support: Select Docker for Windows or Linux operating system.

After the above selection, choose as per your project requirement. Click on the CREATE button to proceed toward creating a new project.

Press F5 to run the project.


You can see the above project executed successfully.

The next step is to publish the project with a CSHTML file by default while publishing all views files compiled and output into one DLL (assembly). No external CSHTML published.

What are the settings for the Project file to publish the CSHTML file while publishing?

Right-click on the project
Select “Unload Project”

Default Content:
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

</Project>

Change the file to the following settings:
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>

    <!-- To publish views instead of views.dll -->
    <EnableDefaultRazorGenerateItems>false</EnableDefaultRazorGenerateItems>
    <EnableDefaultRazorComponentItems>false</EnableDefaultRazorComponentItems>
    <CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.0" />

    <!-- Explicitly include each .cshtml file in the subfolders under Views -->
    <Content Update="Views\**\*.cshtml" CopyToPublishDirectory="PreserveNewest" />
  </ItemGroup>

</Project>

After updating the above settings in the file, close the file again, right-click on the project, and click on “Reload Project”. In the Next step, we set and configure Publish settings.

What are the settings to be done on the publish screen or wizards before publishing?

After Right click on the project, select the “Publish” option.

Select the FOLDER option to publish on the Local Folder and click on the NEXT button.

Select or create a folder where you want to publish the project. Click on the FINISH button after you select the folder location.

Click on Show All settings to set your publish setting more precisely, or directly click on the PUBLISH button. Output of Publish Button:

Error Message: Views\Shared\_Layout.cshtml.css(0,0): Error BLAZOR102: The scoped css file 'Views\Shared\_Layout.cshtml.css' was defined, but no associated razor component or view was found for it.

You can see the error thrown by the publishing process in (Image-10 and Image-11).

Error Solution

Solution 1
You can delete the CSS file “View/Shared/Layout.cshtml” and publish it again.

Solution 2
If you want CSS style or content of the CSS file “View/Shared/Layout.cshtml,” you can create a new CSS file and move this file into the “wwwroot/css” folder and assign the link in the “view/shared/Layout.cshtml” file.


VIEW published successfully

Folder View

You can see in Image-13 and Image-14 Views files were published successfully.



ASP.NET MVC Hosting - HostForLIFE.eu :: Understanding Controller In ASP.NET MVC

clock March 26, 2025 08:41 by author Peter

Here, in this article, we will see more about the controllers and understanding about RouteConfig File. I will be using the same solution which we had used in our previous article. Thus, let's start an introduction.

Open our solution MVCTestApplication, given below:

You can see in our Home Controller class; we have two Action methods; one is Index() and other is HelloAll() . The Index methods are invoked, when you run the Application. Now, just run the Application and you will see:

By default, Hello CsharpCorner has been displayed, because in RouteConfig file, the default action method is Index and we had written “Hello HostForLIFE ” in Index Action Method.

Now, let's type the URL i.e. ControllerName/ActionName and see what we are getting:

As you can see, we had got the same result: “Hello CsharpCorner.” Here, Home is our ControllerName and Index is our Action Method . Similarly, we will see our second Action Method i.e. HelloAll()

As you can see, HelloAll() Action Method has been invoked. Now, let's understand RouteConfig and how these controllers are displayed. Just Open global.asax file in our solution and you will see:

 

Open this file and you will see Application_start () method, in which you will see this line as:

Go to its Definition section, it will redirect to RouteConfig File and you will see:

 

In RouteConfig class, we have default document as:
name:”Default”-Specifies the name

URL: “{Controller}/{action}/{id}” – This line actually says that when you run the solution by default, it will first fire the controllername/index and then Id.

Defaults: As you can see, the default controller' s Home is called and is followed by the action Index and then Id. Note: Here the specified Id is normal and if you want to retrieve the results, you have to pass the Id.

Now, we will see how to pass the Id in our URL and see what output we are getting. Hence, let's start:

In our Homecontroller class, in our Index Action method, just pass a parameter as a string name and return as a name . Now, we will run the Application and see what values we are getting.

When you run the solution, it will ask for the name. Now, let's pass the name in our URL:

As you can see in the output, given above, it had passed Id=1 and got Id=1. Just type Home/index/1 an you will get the output, given above. Now, we will modify the code, write the name and see the output that we will get:

I had passed the name. Now, run the Application. You will see the following output:

Now, just pass the Id and name. We saw the last Id, how to specify the Id or name and how to display it. Now, let's get back to the RouteConfig file and understand the line, given below:

Here, what this line says is: Whatever you are doing in the Controller or in the Index Action method, a trace is getting generated in the form of axd format. We will see how these are generated and how to generate a resource.axd trace. Just open web.config file, shown below:

Just write this line in your web.config file.

Now, run the Application and type trace.axd. You will see the following output:

Click the View details and you will get all the details, shown below:

Scroll down at the bottom of the page and you will see that its path, query string and its respective URLs are:

The trace.axd is useful, when you have built a huge application and you require tracing to find out the details. Conclusion: This was controllers in MVC. I hope you found this article helpful.



ASP.NET MVC Hosting - HostForLIFE.eu :: Using External Projects And Assemblies To Extend MVC Controllers

clock March 18, 2025 07:30 by author Peter

I thought I would take a moment to discuss how one might handle the situation after seeing a recent question on Stack Overflow about how to extend an existing ASP.NET MVC Controller that was present within another assembly or project (i.e., external to the "main" MVC application).

The Fundamental Concept
Assuming you are working on two projects,

  • ProjectA is your primary MVC program.
  • ProjectB is merely a basic class library.

Your goal is to add more controller actions or functionality to an already-existing controller in Project A. These extra steps will originate from a separate project or assembly and won't be included in your primary application. When developing client-specific functionality—that is, when a client requests a certain behavior that might not be pertinent in the main application—this could be helpful.

Thus, for example, your ProjectA controller definition could resemble this:

    namespace ProjectA.Controllers    
    {  
        // This is the primary controller that we want to extend  
        public class FooController : ApplicationController  
        {  
              public ActionResult Index()  
              {  
                  return Content("Foo");  
              }  
        }  
    }   


And you might have a similar class in ProjectB that resembles this,
    namespace ProjectB.Controllers    
    {  
        // You want to essentially add the Bar action to the existing controller  
        public class CustomFooController : FooController  
        {  
            public ActionResult Bar()  
            {  
                return Content("Bar");  
            }  
        }  
    }   


You want to allow all of the different clients to access Foo, but perhaps only a certain client to be exposed to Foo/Bar.

Breaking Down The Steps
This process requires a few different steps that will need to be done to get everything working as expected, which I'll review below,

  • Inheritance
    • The custom controller will inherit from the controller in our main application to streamline extension.
  • Routing
    • Routing can be a tricky business, so using attribute routing might ease some of the burden of fighting with route tables or conflicting controller names.
  • Build Events
    • Build events are just one simple approach to actually getting the necessary .dll files from your custom project into your main application so they can be used.

Taking Advantage of Inheritance
If you actually want to extend the functionality of an existing controller, then inheritance might be the way to go. Inheriting from the controller within your main application will allow you to take advantage of any existing attributes, overridden methods, or underlying base controllers that might already place.

You'll just want to add a reference to your ProjectA project in ProjectB and then target the appropriate controller you wish to inherit from,
    // Other references omitted for brevity  
    using ProjectA.Controllers;  
      
    namespace ProjectB.Controllers    
    {  
        public class CustomFooController : FooController  
        {  
            public ActionResult Bar()  
            {  
                return Content("Bar");  
            }  
        }  
    }   


Leverage Attribute Routing
Doing this kind of thing can get a bit dicey with regards to routing. When you attempt to create this new controller within your current application, it'll attempt to use the existing routes defined in that application, which can lead to naming conflicts and ambiguity if you aren't careful.

Based on the code provided, this means you could easily access /CustomFoo/Bar, but not /Foo/Bar like you might prefer. Thankfully, attribute routing can help with this.

Simply decorate your custom controller action with a [Route] attribute that indicates how you wish to access it,
    [Route("Foo/Bar")]  
    public ActionResult Bar()    
    {  
         return new Content("Bar");  
    }   

This will let MVC know to use map this action to the Foo/Bar URL before taking a look at some of the other routes. In order for attribute routing to work as expected, you'll need to ensure to call the MapMvcAttributeRoutes() method within the RouteConfig.cs file of your main application,
    public static void RegisterRoutes(RouteCollection routes)    
    {  
        // This is important to write up your Route Attributes  
        routes.MapMvcAttributeRoutes();  
      
        // Route declarations omitted for brevity  
    }   


Note
If you were extending a controller that was present within an MVC Area, you would do the same thing within the RegisterArea() method in your AreaRegistration.cs file,
    public override void RegisterArea(AreaRegistrationContext context)    
    {  
        // Wire up any attribute based routing  
        context.Routes.MapMvcAttributeRoutes();  
      
        // Area routing omitted for brevity  
    }   

Properly Scoping Routes
One additional change that will need to be made within your main application will be to prioritize routes within its own namespace. The MapRoute() method supports an overload to handle this via the namespaces parameter.

Set the namespaces parameter to point to the namespaces that you wish to prioritize, namely those in your main application (i.e. "ProjectA.Controllers").
    routes.MapRoute(    
       name: "Default",  
       url: "{controller}/{action}/{id}",  
       defaults: new { controller = "Foo", action = "Index", id = UrlParameter.Optional },  
       // This will prioritize routes within your main application  
       namespaces: new[] { "ProjectA.Controllers"}  
    );   

Putting It All Together
At this point, code-wise, everything should be in place. The only thing left to do is actually get the code from your ProjectB into ProjectA so that you can run it. There are a variety of ways to handle this and configure this entire process, but a very simple one might be through a Build Event. Build Events allow you to execute a bit of code during various stages of the build process.

We are interested in defining a Post-Build event that will move our ProjectB.dll file into the bin directory of ProjectA, which might look like this,
xcopy /E /Y /S "$(ProjectName).dll" "$(SolutionDir)\ProjectA\Bin\"

This would be defined under ProjectB > Properties > Build Events > Post-Build Event Command Line as seen below,

Now if you perform a Rebuild Solution, you should see that all of the proper files have been added to your bin directory as expected,

Now if you were to navigate to /Foo within your application, you would see the content that you might expect,

And likewise, /Foo/Bar should now hit your custom code and do exactly what you'd imagine,




ASP.NET MVC Hosting - HostForLIFE.eu :: ASP.NET MVC Membership Provider

clock March 13, 2025 09:16 by author Peter

Here, we will learn how to use ASP.NET MVC membership provider, create users and their roles using ASP.NET MVC membership, assign roles to users in ASP.NET MVC membership provider, and remove users from roles once we have all user roles from ASP.NET MVC membership. Finally, we will demonstrate how to implement security in ASP.NET MVC applications.

To make security in ASP.NET MVC application use the following method to create the security in ASP.NET MVC application.

Authentication And Authorization in ASP.NET MVC
Authentication: It is the process of checking that the user is valid or not.
Authorization: It is the process of checking that the user is applicable for the process or not.

Membership providers in ASP.NET MVC
Roles based authentication for user in ASP.NET MVC.

We will learn how to create a database for the membership provider in ASP.NET MVC and how to assign role to user, we will create a registration page to understand this.

Let’s create a application for membership provider ASP.NET MVC.
Step 1: Go to visual studio and click on new project -> a window will open from here select a 'ASP.NET MVC4 web application' and give the name for this project in my case I give it as “MVCMembershipProvider "

Now click ok and select a template as Internet Application and engine as Razor engine , after sleeting all these click ok. it will click a solution project this will contain .css file ,script file and MVC application structure.

Step 2: After creation of application let's create a database for this and give the name for this database i gave it as 'MVCApp' and then add a connection string to the database.
    <connectionStrings>  
        <add name="DBConnection" connectionString="Data Source=MUNESH-PC;Database=MVCApp;UID=sa;Password=*****" providerName="System.Data.SqlClient" />  
    </connectionStrings>  


After adding the connection string to the project now we need to create membership tables to the database but before this go to the models folder and have a look on AccountModels.cs class. this class automatically create when we select mvc application as Internet application.

AccountModel.cs class contain following methods.

Now for creating membership tables in database initialize the connection in globel.asax . here we will use code first approach for that we need to add following code in this class.
For adding data table in database membership we need to add a line of code in Global.asax.
WebSecurity.InitializeDatabaseConnection("DBConnection", "UserProfile", "UserId","UserName", autoCreateTables: true);  
Here namespace for WebSecurity is “using WebMatrix.WebData;”

WebSecurity.InitializeDatabaseConnection

Definition for the InitializeDatabaseConnection is:
Public static void InitializeDatabaseConnection (string connectionStringName, stringuserTableName, string userIdColumn, string userNameColumn, bool autoCreateTables);  

connectionStringName: It the name of database table where user information stored.
userTableName: It contain user profile information.
userIdColumn: This column name of table contain user ID this should be integer.
userNameColumn: Column name of table contain user name. This column is basically used to match profile data of user with membership account data.

autoCreateTables: True to indicate that user profile and membership tables should be created if they do not exist; false to indicate that tables should not be created automatically. Although the membership tables can be created automatically, the database itself must already exist.

Now globel.asax page will look like:

Now after all this configuration let's run your application and see the ur hoe page and click on register link which is your page's right side. After running your application you go to the database and see the table, it will generate the following tables for us.

When you will click on registration link the following screen will open with 3 fields.

We can add more fields to this view, for making changes in registration view 1st weneed to add field in database and the  table name is “UserProfile”;


Here we added 3 columns as shown above; now we need to add these column parameters in registration model, it is in Account.cs class which is available in Model.
Code for registration model is:
    public class RegisterModel  
    {  
        [Required]  
        [Display(Name = "User name")]  
        public string UserName  
        {  
            get;  
            set;  
        }  
        [Required]  
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]  
        [DataType(DataType.Password)]  
        [Display(Name = "Password")]  
        public string Password  
        {  
            get;  
            set;  
        }  
        [DataType(DataType.Password)]  
        [Display(Name = "Confirm password")]  
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]  
        public string ConfirmPassword  
        {  
            get;  
            set;  
        }  
        [Required]  
        [Display(Name = "EmailID")]  
        public string EmailId  
        {  
            get;  
            set;  
        }  
        [Required]  
        [Display(Name = "address")]  
        public string Address  
        {  
            get;  
            set;  
        }  
        [Required]  
        [Display(Name = "Mobile No")]  
        public string MobileNo  
        {  
            get;  
            set;  
        }  
    }  


Add these field in registration view:
    <fieldset>  
        <legend>Registration Form</legend>  
        <ol>  
            <li>  
                @Html.LabelFor(m => m.UserName) @Html.TextBoxFor(m => m.UserName)  
            </li>  
            <li>  
                @Html.LabelFor(m => m.Password) @Html. PasswordFor (m => m.Password)  
            </li>  
            <li>  
                @Html.LabelFor(m => m.ConfirmPassword) @Html.PasswordFor(m => m.ConfirmPassword)  
            </li>  
            <li>  
                @Html.LabelFor(m => m.EmailId) @Html.TextBoxFor(m => m.EmailId)  
            </li>  
            <li>  
                @Html.LabelFor(m => m.Address) @Html.TextBoxFor(m => m.Address)  
            </li>  
            <li>  
                @Html.LabelFor(m => m.MobileNo) @Html.TextBoxFor(m => m.MobileNo)  
            </li>  
        </ol>  
        <input type="submit" value="Register" />  
    </fieldset>  


Now if you will run your application and you will see registration page it will look with new fields.

Now according to this we need to add or handle these field in controller also so for that go to Account Controller and we have to make changes in HTTPPost method of registration Action.

Now the code for this action according to old registration model is:
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);  

Now will make changes in this according to new model:
    WebSecurity.CreateUserAndAccount(model.UserName, model.Password,  
    new  
    {  
       EmailID = model.EmailId,  
       Address = model.Address,  
       MobileNo = model.MobileNo  
    }  
    );  

So the code for the Registration action method is:

    [HttpPost]  
    [AllowAnonymous]  
    [ValidateAntiForgeryToken]  
    public ActionResult Register(RegisterModel model)  
    {  
        if (ModelState.IsValid)  
        {  
            // Attempt to register the user  
            try  
            {  
                WebSecurity.CreateUserAndAccount(model.UserName, model.Password,  
                    new  
                    {  
                        EmailID = model.EmailId,  
                            Address = model.Address,  
                            MobileNo = model.MobileNo  
                    }  
                );  
                WebSecurity.Login(model.UserName, model.Password);  
                return RedirectToAction("Index", "Home");  
            }  
            catch (MembershipCreateUserException e)  
            {  
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));  
            }  
        }  
        // If we got this far, something failed, redisplay form  
        return View(model);  
    }  


Now run your application and go to registration page and enter some data to fields then save it ,data will save in database.



ASP.NET MVC Hosting - HostForLIFE.eu :: Stripe Payment Gateway Integration with ASP.NET Core MVC

clock February 10, 2025 07:09 by author Peter

We'll go over every step of integrating the Stripe Payment Gateway into an ASP.NET Core MVC application in this post. After completing this tutorial, you will have a complete payment system that enables customers to use Stripe's safe checkout to make purchases.

Stripe is a popular payment gateway that allows businesses to accept payments online. It supports credit cards, debit cards, and other payment methods. Stripe provides a secure and easy-to-integrate API for developers. In this article, we’ll use Stripe Checkout, which is a pre-built payment page hosted by Stripe. This approach is secure and requires minimal setup.

Introduction
Before starting, ensure you have the following.

  • Stripe Account: Sign up at Stripe.
  • .NET SDK: Install the latest .NET SDK from here.
  • IDE: Use Visual Studio, Visual Studio Code, or any preferred IDE.
  • Stripe API Keys: Retrieve your Publishable Key and Secret Key from the Stripe Dashboard.

Step 1. Create a Stripe Account

  1. Go to Stripe and sign up for an account.
  2. Once logged in, navigate to Developers > API Keys.
  3. Copy your publishable key and secret key. These will be used in your ASP.NET Core application.

Step 2. Set Up an ASP.NET Core MVC Project

  • Open Visual Studio or your preferred IDE.
  • Create a new ASP.NET Core Web App (Model-View-Controller) project.
    • Name the project (e.g., StripePaymentDemo).
    • Select .NET 6.0 or later as the framework.
  • Build and run the project to ensure it’s set up correctly.

Step 3. Install Stripe.NET NuGet Package
Stripe provides an official .NET library to interact with its API. Install it via the Package Manager Console.
Install-Package Stripe.net

Step 4. Configure Stripe in appsettings.json
Add your Stripe API keys to the appsettings.json file.
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Stripe": {
    "PublishableKey": "YOUR_STRIPE_PUBLISHED_KEY",
    "SecretKey": "YOUR_SECRET_KEY"
  },
  "AllowedHosts": "*"
}

Step 5. Configure Stripe in the Program.cs
Configure Stripe in the Program.cs file.
using Stripe;

namespace StripePaymentDemoApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            // Add services to the container
            builder.Services.AddControllersWithViews();
            StripeConfiguration.ApiKey = builder.Configuration["Stripe:SecretKey"];
            var app = builder.Build();
            // Configure the HTTP request pipeline
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios,
                // see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            app.Run();
        }
    }
}

Step 6. Create a Payment Controller
Create a new controller named: PaymentController.cs.using Microsoft.AspNetCore.Mvc;
using Stripe.Checkout;

namespace StripePaymentDemoApp.Controllers
{
    public class PaymentController : Controller
    {
        private readonly IConfiguration _configuration;
        public PaymentController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        public IActionResult Checkout()
        {
            // Pass the Stripe Publishable Key to the view
            ViewBag.StripePublishableKey = _configuration["Stripe:PublishableKey"];
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> CreateCheckoutSession()
        {
            // Create a Stripe Checkout Session
            var options = new SessionCreateOptions
            {
                PaymentMethodTypes = new List<string> { "card" },
                LineItems = new List<SessionLineItemOptions>
                {
                    new SessionLineItemOptions
                    {
                        PriceData = new SessionLineItemPriceDataOptions
                        {
                            Currency = "usd",
                            ProductData = new SessionLineItemPriceDataProductDataOptions
                            {
                                Name = "Test Product",
                            },
                            UnitAmount = 2000, // $20.00 (in cents)
                        },
                        Quantity = 1,
                    },
                },
                Mode = "payment",
                SuccessUrl = Url.Action("Success", "Payment", null, Request.Scheme),
                CancelUrl = Url.Action("Cancel", "Payment", null, Request.Scheme),
            };
            var service = new SessionService();
            var session = await service.CreateAsync(options);
            // Redirect to Stripe Checkout
            return Redirect(session.Url);
        }
        public IActionResult Success()
        {
            return View();
        }
        public IActionResult Cancel()
        {
            return View();
        }
    }
}
Step 7. Create Views
Checkout View (Views/Payment/Checkout.cshtml).
@{
ViewData["Title"] = "Checkout";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Checkout</h1>
<form asp-action="CreateCheckoutSession" method="post">
<button type="submit" class="btn btn-primary">Pay with Stripe</button>
</form>


Success View (Views/Payment/Success.cshtml).
@{
ViewData["Title"] = "Payment Successful";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Payment Successful</h1>
<p>Thank you for your payment!</p>

Cancel View (Views/Payment/Cancel.cshtml).
@{
ViewData["Title"] = "Payment Canceled";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Payment Canceled</h1>
<p>Your payment was canceled.</p>

Step 8. Run and Test the Application

  • Run the application using dotnet run or your IDE’s run command.
  • Navigate to /Payment/Checkout in your browser.
  • Click the "Pay with Stripe" button to be redirected to the Stripe Checkout page.
  • Use the following test card details.
    • Card Number: 4242 4242 4242 4242.
    • Expiration Date: Any future date.
    • CVC: Any 3 digits.
    • ZIP Code: Any value.

Let's run the application and start the payments with Stripe.

Click the Pay with Stripe Button.


Fill in the payment details with test credentials and click the pay button.

Let's look at our most recent transactions on the Stripe dashboard.


Step 9. Handle Webhooks (Optional)
To handle payment confirmation and other events, set up a webhook endpoint.

Create a Webhook Endpoint in the Stripe Dashboard.

  • Go to Developers > Webhooks in the Stripe Dashboard.
    • Add a new endpoint with your server's URL (e.g., https://yourdomain.com/Payment/Webhook).
    • Add Webhook Secret to:appsettings.json.

{
  "Stripe": {
    "WebhookSecret": "your_webhook_secret_here"
  }
}


Add Webhook Handler in:PaymentController.cs.
[HttpPost]
public async Task<IActionResult> Webhook()
{
    var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();

    try
    {
        var stripeEvent = EventUtility.ConstructEvent(
            json,
            Request.Headers["Stripe-Signature"],
            _configuration["Stripe:WebhookSecret"]
        );
        // Handle events
        if (stripeEvent.Type == Events.CheckoutSessionCompleted)
        {
            var session = stripeEvent.Data.Object as Session;
            // Handle successful payment
        }
        return Ok();
    }
    catch (StripeException e)
    {
        return BadRequest();
    }
}



ASP.NET MVC Hosting - HostForLIFE.eu :: Scalable ASP.NET MVC Application Design Patterns

clock February 3, 2025 06:14 by author Peter

Design patterns are tried-and-true fixes for typical program design issues. Implementing these principles can enhance the scalability, testability, and maintainability of code in ASP.NET MVC projects. This article examines important design patterns seen in ASP.NET MVC projects and offers real-world examples of how to use them.

1. Repository Pattern
The repository pattern abstracts data access logic, providing a clean separation between the business logic and the data layer.

Benefits

  • Promotes loose coupling between the application and data storage.
  • Simplifies unit testing by allowing mocking of the data layer.

Implementation
// IRepository Interface
public interface IRepository<T> where T : class
{
    IEnumerable<T> GetAll();
    T GetById(int id);
    void Insert(T entity);
    void Update(T entity);
    void Delete(int id);
}

// Repository Implementation
public class Repository<T> : IRepository<T> where T : class
{
    private readonly ApplicationDbContext _context;
    private DbSet<T> entities;

    public Repository(ApplicationDbContext context)
    {
        _context = context;
        entities = context.Set<T>();
    }

    public IEnumerable<T> GetAll() => entities.ToList();
    public T GetById(int id) => entities.Find(id);
    public void Insert(T entity) => entities.Add(entity);
    public void Update(T entity) => _context.Entry(entity).State = EntityState.Modified;
    public void Delete(int id) => entities.Remove(GetById(id));
}


2. Unit of Work Pattern
The unit of work pattern helps manage transactions by coordinating changes across multiple repositories in a single transaction.

Benefits

  • Ensures consistency across repositories.
  • Reduces redundant calls to the database.

Implementation
public class UnitOfWork : IDisposable
{
    private readonly ApplicationDbContext _context;
    private IRepository<Product> _productRepository;

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

    public IRepository<Product> ProductRepository
    {
        get
        {
            return _productRepository ??= new Repository<Product>(_context);
        }
    }

    public void Save()
    {
        _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}


3. Dependency Injection (DI)
Dependency injection (DI) injects dependencies into controllers or classes instead of creating them directly.

Benefits

  • Reduces tight coupling.
  • Simplifies testing by allowing dependency substitution.

Implementation
Configure DI in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IRepository<Product>, Repository<Product>>();
    services.AddScoped<UnitOfWork>();
    services.AddControllersWithViews();
}


Inject Dependencies in Controller
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int StockQuantity { get; set; }
}

Products Controller
using System.Linq;
using System.Web.Mvc;
using MVCDesignPatternsApp.Models;
using MVCDesignPatternsApp.Repositories;

public class ProductsController : Controller
{
    private readonly UnitOfWork _unitOfWork;

    public ProductsController(UnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    // GET: Products
    public ActionResult Index()
    {
        var products = _unitOfWork.ProductRepository.GetAll().ToList();
        return View(products);
    }

    // GET: Products/Details/5
    public ActionResult Details(int id)
    {
        var product = _unitOfWork.ProductRepository.GetById(id);
        if (product == null)
        {
            return HttpNotFound();
        }
        return View(product);
    }

    // GET: Products/Create
    public ActionResult Create()
    {
        return View();
    }

    // POST: Products/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Product product)
    {
        if (ModelState.IsValid)
        {
            _unitOfWork.ProductRepository.Insert(product);
            _unitOfWork.Save();
            return RedirectToAction("Index");
        }
        return View(product);
    }

    // GET: Products/Edit/5
    public ActionResult Edit(int id)
    {
        var product = _unitOfWork.ProductRepository.GetById(id);
        if (product == null)
        {
            return HttpNotFound();
        }
        return View(product);
    }

    // POST: Products/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(Product product)
    {
        if (ModelState.IsValid)
        {
            _unitOfWork.ProductRepository.Update(product);
            _unitOfWork.Save();
            return RedirectToAction("Index");
        }
        return View(product);
    }

    // GET: Products/Delete/5
    public ActionResult Delete(int id)
    {
        var product = _unitOfWork.ProductRepository.GetById(id);
        if (product == null)
        {
            return HttpNotFound();
        }
        return View(product);
    }

    // POST: Products/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        _unitOfWork.ProductRepository.Delete(id);
        _unitOfWork.Save();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _unitOfWork.Dispose();
        }
        base.Dispose(disposing);
    }
}

Views
Ensure you have corresponding views in the Views/Products/ folder:

  • Index.cshtml: Display the product list.
  • Details.cshtml: Show product details.
  • Create.cshtml: Form to add a new product.
  • Edit.cshtml: Form to update product information.
  • Delete.cshtml: Confirm product deletion.

View Example for Index.cshtml
@model IEnumerable<YourNamespace.Models.Product>

<h2>Product List</h2>

<p>
    @Html.ActionLink("Create New Product", "Create")
</p>

<table class="table">
    <thead>
        <tr>
            <th>Name</th>
            <th>Price</th>
            <th>Stock Quantity</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
    @foreach (var item in Model) {
        <tr>
            <td>@item.Name</td>
            <td>@item.Price</td>
            <td>@item.StockQuantity</td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }
    </tbody>
</table>

4. Factory Pattern
The factory pattern centralizes object creation logic.

Benefits

  • Decouples object creation from usage.
  • Promotes flexibility for varying object requirements.

Implementation
Factory Implementation

public interface IProductService
{
    void ProcessOrder();
}

public class PhysicalProductService : IProductService
{
    public void ProcessOrder() => Console.WriteLine("Processing physical product order.");
}

public class DigitalProductService : IProductService
{
    public void ProcessOrder() => Console.WriteLine("Processing digital product order.");
}

public class ProductServiceFactory
{
    public IProductService GetProductService(string productType)
    {
        return productType switch
        {
            "Physical" => new PhysicalProductService(),
            "Digital" => new DigitalProductService(),
            _ => throw new ArgumentException("Invalid product type")
        };
    }
}

Usage in Controller
public class OrdersController : Controller
{
    private readonly ProductServiceFactory _factory;

    public OrdersController(ProductServiceFactory factory)
    {
        _factory = factory;
    }

    public void CreateOrder(string productType)
    {
        var service = _factory.GetProductService(productType);
        service.ProcessOrder();
    }
}

5. Singleton Pattern
The singleton pattern ensures only one instance of a class is created and shared.

Benefits

  • Ideal for shared resources like logging or caching.
  • Ensures a single point of control.

Implementation
Singleton Class
public sealed class LogManager
{
    private static readonly Lazy<LogManager> instance = new(() => new LogManager());

    private LogManager() { }

    public static LogManager Instance => instance.Value;

    public void Log(string message) => Console.WriteLine($"Log: {message}");
}


6. Command Pattern
The command pattern encapsulates a request as an object, allowing for more complex request handling.

Benefits

  • Supports undoable operations.
  • Decouples request handling from request execution.

Implementation
Command Interface and Implementation
public interface ICommand
{
    void Execute();
}

public class SaveOrderCommand : ICommand
{
    public void Execute() => Console.WriteLine("Order saved.");
}

public class CancelOrderCommand : ICommand
{
    public void Execute() => Console.WriteLine("Order canceled.");
}

Invoker Class
public class CommandInvoker
{
    private readonly List<ICommand> _commands = new();

    public void AddCommand(ICommand command) => _commands.Add(command);

    public void ExecuteCommands()
    {
        foreach (var command in _commands)
        {
            command.Execute();
        }
        _commands.Clear();
    }
}

Output

 



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in