European ASP.NET MVC Hosting

BLOG about Latest ASP.NET MVC Hosting and Its Technology - Dedicated to European Windows Hosting Customer

ASP.NET MVC Hosting - HostForLIFEASP.NET :: MVC Architecture & MVC Life Cycle

clock October 25, 2024 08:58 by author Peter

Model View Controller, or MVC for short, is a design pattern used to create applications rather than a programming language. Three components will make up the application that was created utilizing the MVC design pattern. Which model will house all of the data that can be retrieved at the user's request?

The Controller will have business logic code, and the View will have user interface code. We shall examine a graphical example of MVC to gain a better understanding of it.

The Properties of MVC is.

  • Loose Coupling
  • Lightweight code
  • Effective look
  • Testing is Very Easy
  • Rapid application integrated development.

MVC Architecture
The architecture of MVC can be seen in the following figure.

Explanation
User will make request for the page which user would like to retrieve. Requested page will go to controller and on controller Route.Config will be checked. Requested page will get transfer to Model from Controller.

On Model there will be 2 steps.

  • Page initialization will get started.
  • Then result set will be generated.

After these operation result set will get unload to View through view engine.

Responsibility of view engine

  • View Engine get the request from Controller
  • The requested page will get executed
  • The result got by the execution process will get deliver to View.

Life cycle of MVC
Life Cycle of MVC is in the following figure.

Explanation of MVC Life Cycle
Step 1. User will make request for page
Step 2. Route.Config will get check on Controller
Step 3. After Route.Config validation request will get transfer from Controller to Model
Step 4. Page request will go to Model & on Model the following operation will perform.

  • Page initialization will start after the initialization of the page.
  • One result set will get generated.

Step 5. Generated result set will be delivered to the Controller from the Model.
On Model Page validation operation will perform.

Step 6. After page validation on controller, Page will deliver to View through View engine.

Step 7. Now user can see requested page as response page.
Life Cycle of MVC can be seen as in the following figure.


Explanation

  • User will make page request.
  • Route.Config of requested page will get checked on Controller.
  • Page initialization will be performing on Model and after page initialization one result set will get generated.
  • Generated Result set will be getting delivered to the Controller from Model.
  • Result set will get validated (Page Validation) and after page validation Result set will get delivred to View through view engine.

Recap
MVC Stands for Model View Controller, which is a design pattern. MVC based developed application will get divided in 3 components. Each and every component will contain their own code only.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: How To Create ASP.NET Core MVC Application?

clock October 11, 2024 08:47 by author Peter

In this article, we will learn how to create an ASP.NET Core MVC web application step by step. Prior to creating the application, let's know about the ASP.NET Core.

What is ASP.NET Core?
ASP.NET Core is an open-source cross-platform framework for developing and building web, cloud, and IoT applications.

Why should we use ASP.NET Core?

  • ASP.NET is an open-source platform that runs on Microsoft .NET Core Framework.
  • We can build and run the ASP.NET core application on a cross-platform environment such as Windows, macOS, Linux, etc.
  • We can build modern apps such as Cloud, IoT, Web apps, mobile backend, etc. and those can be easily enabled to run over the cloud platform.
  • We can host applications on any modern platform such as docker, AKS, or any environment.
  • Saves the efforts of the developer with built-in features such as dependency injection, you can enable docker, containerization, and swagger support in just one click.

Now let's start creating an ASP.NET Core MVC web application.

Step 1. Open Visual Studio.
Open Visual Studio ( I am using 2019)
Once the Visual Studio Opens, Then click on Continue Without Code as shown in the following image.

Then from the Visual Studio Menu, click on File => New Project, as shown in the following image.

Click on the New Project, then the following window appears as shown in step 2.

Step 2. Choose Project Template
You will see the two project templates.

  • ASP.NET Core Web App: This project template creates the web application with Razor pages without a Model, View, or Controller.
  • ASP.NET Core Web App (Model-View-Controller): This project template creates the web application with Model, View, Controller (MVC).

Choose the ASP.NET Core Web App(Model-View-Controller) Template as shown in the following image.

After choosing the project template click on Next.

Step 3. Define Project Name and Location
In the project configuration window, you will see the following options.

  • Project Name: Define any name for your project as per your choice.
  • Location: Choose the location to save the project files on your hard drive of the machine. I have chosen the Project/VS folder of the E drive of the machine, and obviously, it's different on your computer.
  • Solution Name: The solution name is auto-defined based on the project name, but you can change the name based on your own choice.

Additionally, there is a checkbox, if you have checked it, then the solution file (.sln) and project files will be saved in the same folder. Now Choose the minimum details for ease of understanding as shown in the following image.

After defining the required details, click on the Next.

Step 4. Choose the Target Framework
Choose the target framework .NET 5 which is the latest or you can choose based on your requirements, skip the other details for ease of understanding as shown in the following image.

After providing the required details, click the create button. It will create the ASP.NET Core MVC web application as shown in step 5.

Step 5. Understanding ASP.NET Core MVC Folder Structure
The following is the default folder structure of the ASP.NET Core ASP.NET MVC application.

 

Let's understand the preceding project folder structure in brief.

  • The wwwroot folder: The wwwroot is the default root folder for storing the static files related to the project and those files can be accessed programmatically with a relative path.
  • Controller Folder: The controller folder contains the controller classes where the operation-related code is written.
  • Model Folder: The Models Folder contains the domain or entity classes. Models can be written anywhere in the solution such as in a separate class library or folder etc.
  • Views Folder: The Views folder holds the razor pages which are responsible for showing and getting the data from the users.
  • The appsettings.json File: The appsettings.json folder contains the configuration and secret details of the application.
  • Program.cs File: The Program.cs is the starting point of the application which will create the host for an application to run the application.
  • Startup.cs File: The Startup.cs file allows to configuration of the behavior of the application such as defining the routes, dependency injection, etc.

Step 6. Run the ASP.NET Core MVC Application
You can run the application with default contents or let open the Index.cshtml file and put some contents there. Now press F5 on the keyboard or use the run option from Visual Studio to run the application in the browser. After running the application, it will show in the browser as shown in the following image.|



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Attribute Routing Overview in MVC and .NET Core

clock September 4, 2024 08:36 by author Peter

Attribute routing is a potent feature in ASP.NET Core that lets you explicitly define routing information on controller activities. Compared to traditional routing, this offers more flexibility and control over how HTTP requests are routed to your API endpoints. This is a summary of attribute routing's functions and how to use it in your.NET Core API.


Attribute Routing: What is It?

With attribute routing, you may use attributes to construct routes directly on your action methods or controllers. This method can help make routing easier to comprehend and control because it is more explicit.

How to use Attribute Routing?
1. Basic Attribute Routing

You can apply routing attributes directly to action methods and controllers. For example.

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    // GET api/products
    [HttpGet]
    public IActionResult GetAllProducts()
    {
        // Implementation
    }
    // GET api/products/5
    [HttpGet("{id}")]
    public IActionResult GetProductById(int id)
    {
        // Implementation
    }
    // POST api/products
    [HttpPost]
    public IActionResult CreateProduct([FromBody] Product product)
    {
        // Implementation
    }
}


Controller Route: [Route("api/[controller]")] sets the base route for all actions in the controller. [controller] is a placeholder that gets replaced with the name of the controller (e.g., Products).
Action Routes: [HttpGet], [HttpGet("{id}")], [HttpPost] specify the HTTP methods and the routes for the actions.

2. Route Parameters
You can use route parameters in the attribute routing to capture values from the URL.

[HttpGet("search/{query}")]
public IActionResult SearchProducts(string query)
{
    // Implementation
}

Route Parameter: {query} in the route template will capture the value from the URL and pass it to the action method.

3. Optional Parameters
To make route parameters optional, use the following syntax.
[HttpGet("items/{id?}")]
public IActionResult GetItemById(int? id)
{
    // Implementation
}


Optional Parameter: {id?} makes the id parameter optional.

4. Route Constraints
You can add constraints to route parameters to enforce specific patterns.
[HttpGet("products/{id:int}")]
public IActionResult GetProductById(int id)
{
    // Implementation
}

Route Constraint: {id:int} ensures that the id parameter must be an integer.

5. Route Prefixes and Constraints at Controller Level
You can also set route prefixes and constraints at the controller level.
[ApiController]
[Route("api/[controller]/[action]")]
public class OrdersController : ControllerBase
{
    [HttpGet]
    public IActionResult GetAllOrders()
    {
        // Implementation
    }

    [HttpGet("{id:int}")]
    public IActionResult GetOrderById(int id)
    {
        // Implementation
    }
}

Action Route: [action] is replaced with the action method name in the route URL.

6. Combining Routes
You can combine routes and use route templates to create complex routing scenarios.
[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    [HttpGet("{customerId}/orders/{orderId}")]
    public IActionResult GetCustomerOrder(int customerId, int orderId)
    {
        // Implementation
    }
}

Benefits of Attribute Routing
Clarity and Control: Route definitions are more explicit and closely related to their corresponding actions, making it easier to understand and manage routes.
Flexibility: Allows for more complex routing scenarios, including optional and default parameters, constraints, and combined routes.
Customization: Facilitates precise control over route templates and endpoints.

Combined Route
The route combines customerId and orderId parameters to define a more specific endpoint.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Different ActionResult Types in ASP.NET MVC & Their Uses

clock April 2, 2024 07:32 by author Peter

In ASP.NET MVC, the ActionResult class plays a crucial part in the result that is sent to the client when an action method is invoked. It's important to know the different ActionResult types and when to use them when developing MVC applications that are both secure and effective. This article will examine the various types of ActionResult and provide usage examples.

View Outcome

  • Use this technique when producing an entire HTML view in response to a user request.
  • typically used to display entire views or pages containing significant information.
  • ideal for displaying intricate information representations or user interface components.

public ActionResult Index()
{
    return View();
}


PartialViewResult

  • Purpose- Including particular page portions by rendering partial views.
  • Use Case- Perfect for containing reusable user interface elements such as sidebars, footers, headers, or widgets.Helps in maintaining modular and reusable code by separating UI components into smaller parts.


public ActionResult Sidebar()
{
    return PartialView("_Sidebar");
}


RedirectResult

  • Use when the client needs to be redirected to an alternative URL.
  • frequently used following successful login/logout processes, form submissions, or the permanent move of a resource.
  • helpful for handling URL changes or for putting HTTP redirects into place for SEO reasons.


public ActionResult RedirectCsharpcorner()
{
    return Redirect("https://www.c-sharpcorner.com/");
}

RedirectToRouteResult

  • Use in cases where route values require redirecting to an alternative action method inside the same application.
  • especially when utilizing named routes, useful for navigating around the application.
  • makes redirecting based on routing configuration possible in a more organized manner.


public ActionResult RedirectToAction()
{
    return RedirectToAction("Index", "Home");
}


JsonResult

  • Use in situations where you must give the client data in JSON format.
  • Perfect for creating online APIs that use JSON for data interchange or for AJAX requests.
  • makes it possible for client-side JavaScript frameworks to efficiently consume data without requiring refreshing entire pages.


public ActionResult GetJsonData()
{
    var data = new { Name = "Peter", Age = 25 };
    return Json(data, JsonRequestBehavior.AllowGet);
}


ContentResult

  • Use this method when you have to send the client plain text or HTML as raw material.
  • Ideal for producing dynamic content such as error warnings, delivering short replies, or presenting static material.
  • allows you to create and deliver content directly from the controller action with more flexibility.


public ActionResult ContentText()
{
    return Content("This is plain text content.");
}


FileResult

  • Use this if you need to download a document or an image and then return it to the client.
  • permits users to download data from the program, including Excel spreadsheets, photos, and PDFs.
  • allows for the customization of the file name and content type while offering a smooth method of file serving.


public ActionResult DownloadFile()
{
    byte[] fileBytes = System.IO.File.ReadAllBytes("path_to_file.pdf");
    return File(fileBytes, "application/pdf", "filename.pdf");
}


HttpStatusCodeResult

  • Use this when you need to provide the client with just a certain HTTP status number and no more content.
  • useful for indicating different HTTP status codes, such as redirection, success, and client or server issues.
  • permits appropriate HTTP status code processing to improve server-client communication.


public ActionResult Index()
{
    // Return HTTP 404 (Not Found) status code
    return new HttpStatusCodeResult(HttpStatusCode.NotFound);
}


EmptyResult

  • Use in situations where an action method doesn't need to give the client any data; this is usually the case for actions that have side effects.
  • Ideal for situations where the answer is not important in and of itself, like logging actions or updating database entries.
  • helps in keeping the answer brief and effective when the client doesn't need any data to be returned.


​public ActionResult ClearCache()
{
    // Code to clear cache goes here
    // For example:
    Cache.Clear();

    // Return EmptyResult since no data needs to be sent back to the client
    return new EmptyResult();
}

Developers have a lot of options when it comes to creating dynamic and responsive web apps with the diverse range of ActionResult types available in ASP.NET MVC. Through an understanding of the subtle differences between each ActionResult subtype and matching them to the particular needs of their applications, developers may coordinate smooth server-client interactions, improving the user experience in general.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: How to Restrict Uploaded File Type in ASP.NET Core?

clock March 15, 2024 08:57 by author Peter

In ASP.NET Core MVC, you can restrict the file types that can be uploaded by adding server-side validation. Here's a simple example of how to accomplish this:

Why do we need to restrict uploaded File Type in an ASP.NET Core?

  • Security: Allowing unrestricted file uploads can pose security risks. Certain file types, such as executable files (.exe), scripts (.js, .ps1), or files containing macros (.docm), could be used to execute malicious code on the server or client-side when downloaded. Restricting file types mitigates these risks by preventing potentially harmful files from being uploaded.
  • Data Integrity: Limiting the accepted file types ensures that the application only processes files that are compatible with its functionality. Accepting only specific file types reduces the chances of errors or unexpected behavior caused by unsupported file formats.
  • Compliance: In some industries or applications, there might be regulatory or compliance requirements regarding the types of files that can be uploaded. Enforcing restrictions helps ensure compliance with such standards.
  • Resource Management: Different file types require different processing and storage resources. By restricting the allowed file types, you can better manage server resources and avoid unnecessary strain on the system.
  • User Experience: Providing clear restrictions on acceptable file types helps users understand what they can upload, reducing confusion and errors during the file upload process. This improves the overall user experience of the application.

1-Client-Side Validation (Optional): You can use the HTML5 accept attribute on your file input to restrict file types. However, keep in mind that this can be easily bypassed by users, so server-side validation is essential.
<input type="file" name="file" accept=".pdf,.doc,.docx">

2. Server-Side Validation: In your controller action, where you handle the file upload, you can check the file's content type or extension and reject files that are not allowed.
Add a controller

  • In Solution Explorer, right-click Controllers > Add > Controller.
  • In the Add New Scaffolded Item dialog box, select MVC Controller - Empty > Add.
  • In the Add New Item - RestrictUploadedFileSize_Demo dialog, enter FileUploadController.cs and select Add.

Replace the contents of Controllers/ FileUploadController.cs with the following code.
using Microsoft.AspNetCore.Mvc;

namespace RestrictUploadedFileSize_Demo.Controllers
{
    public class FileUploadController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> FileUpload(IFormFile SingleFile)
        {
            if (SingleFile == null || SingleFile.Length == 0)
            {
                ModelState.AddModelError("", "File not selected");
                return View("Index");
            }

            var permittedExtensions = new[] { ".jpg", ".png", ".gif" };
            var extension = Path.GetExtension(SingleFile.FileName).ToLowerInvariant();

            if (string.IsNullOrEmpty(extension) || !permittedExtensions.Contains(extension))
            {
                ModelState.AddModelError("", "Invalid file type.");
            }

            // Optional: Validate MIME type as well
            var mimeType = SingleFile.ContentType;
            var permittedMimeTypes = new[] { "image/jpeg", "image/png", "image/gif" };
            if (!permittedMimeTypes.Contains(mimeType))
            {
                ModelState.AddModelError("", "Invalid MIME type.");
            }

            //Validating the File Size
            if (SingleFile.Length > 10000000) // Limit to 10 MB
            {
                ModelState.AddModelError("", "The file is too large.");
            }

            if (ModelState.IsValid)
            {
                var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads", SingleFile.FileName);

                //Using Streaming
                using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                {
                    await SingleFile.CopyToAsync(stream);
                }

                // Process the file here (e.g., save to the database, storage, etc.)
                return View("UploadSuccess");
            }

            return View("Index");
        }
    }
}


This code snippet checks both the file extension and content type to ensure that it meets your criteria. You can adjust the allowed file types and content types according to your requirements. Additionally, you can improve this validation logic based on your specific needs, such as checking the file's signature or using a more comprehensive file type validation library.Add a view

  • Right-click on the Views folder, then Add > New Folder and name the folder Companies
  • Right-click on the Views/ FileUpload folder, and then Add > New Item.
  • In the Add New Item dialog, select Show All Templates.
  • In the Add New Item - RestrictUploadedFileSize_Demo dialog:
  • In the search box in the upper-right, enter the view
  • Select Razor View - Empty
  • Keep the Name box value, Index.cshtml.
  • Select Add
  • Replace the contents of the Views/Companies/Index.cshtml Razor view file with the following:

Index.cshtml
@{
    ViewData["Title"] = "Index";
}

<h2>File Upload</h2>
<hr />
<div class="row">
    <div class="col-md-12">
        <form method="post" asp-controller="FileUpload" asp-action="FileUpload"enctype="multipart/form-data">
            <div asp-validation-summary="All" class="text-danger"></div>
            <input type="file" name="SingleFile" class="form-control" />
            <button type="submit" name="Upload" class="btn btn-primary">Upload</button>
        </form>
    </div>
</div>


Run the Application

Select Ctrl+F5 to run the app without the debugger. Visual Studio runs the ASP.NET app and opens the default browser.

Restricting uploaded file types in ASP.NET Core increases security, data integrity, regulatory compliance, resource efficiency, and user experience. It's a critical component of developing robust and secure web apps.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Session Management in ASP.NET Core MVC

clock March 4, 2024 08:32 by author Peter

Importance of Sessions in Web Applications
Sessions bridge this gap by providing a means to preserve user-specific data across multiple requests within a defined period.

  • Maintain User Identity: Sessions are instrumental in user authentication and authorization processes. They allow web applications to identify and track users across various interactions, ensuring secure access to restricted resources.
  • Customized User Experience: Sessions facilitate the personalization of user experiences by storing user preferences, settings, and browsing history. This enables applications to tailor content and functionality based on individual user profiles.
  • Shopping Carts and E-commerce: In e-commerce applications, sessions are indispensable for managing shopping carts and order processing. By persisting cart contents and user selections across page transitions, sessions streamline the purchasing journey and enhance user convenience.
  • Form Persistence: Sessions enable the retention of form data entered by users, safeguarding against data loss during navigation or submission errors. This ensures a seamless and uninterrupted form-filling experience.
  • Tracking User Activity: Sessions empower web analytics and tracking mechanisms by storing user session data, such as page views, interactions, and session duration. This information aids in understanding user behavior and optimizing website performance.

Implement Session Management in ASP.NET Core MVC
Create a New ASP.NET Core MVC Project: Start by creating a new ASP.NET Core MVC project in Visual Studio or using the .NET CLI.

Install Required Packages
Install the required packages for session management using NuGet Package Manager or the .NET CLI. In this example, we'll need the Microsoft.AspNetCore.Session package.

Configure Services

In the ConfigureServices method of the Startup class, add the session services using services.AddSession().

Configure Middleware

In the Configure method of the Startup class, use the session middleware using the app.UseSession().

Create Controllers

Create controllers to handle your application's logic. For this example, we'll use HomeController and RecordsController.

Here I have created a home cotroller with an Index action method to set data into session.
public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        // Add list of records to session
        var records = new List<Record>
        {
            new Record { Id = 1, Name = "Record 1" },
            new Record { Id = 2, Name = "Record 2" },
            // Add more records here as needed
        };

        var serializedRecords = JsonSerializer.Serialize(records);
        HttpContext.Session.SetString("Records", serializedRecords);
        return RedirectToAction("GetRecords", "Records");
    }
}


Store Data in Session
In one of your controller actions (for example, the Index action of HomeController), store the data you want to maintain in the session. Serialize complex types like lists into strings or byte arrays before storing them.

I have stored data using var serializedRecords = JsonSerializer.Serialize(records);

Retrieve Data from Session
In another controller action (for example, the GetRecords action of RecordsController), retrieve the data from the session. Deserialize the stored data back into its original type if necessary.

public class RecordsController : Controller
{
    public IActionResult GetRecords()
    {
        // Retrieve list of records from session
        var records = HttpContext.Session.Get<List<Record>>("Records");
        return View(records);
    }
}


Summary
Session management is a fundamental aspect of web development, enabling developers to create interactive, personalized, and secure web applications.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Custom Filter In MVC Or Logging Using MVC Filter

clock February 15, 2024 08:34 by author Peter

In my MVC project, I want to build a filter that records every controller action. All I'm doing is injecting an ILogger object to log the logs into my table storage. This blog post explains how to make an action filter and how to add it to any action, controller, or global location.


Make an Action filter class:

    namespace Filter {  
        using System;  
        using Microsoft.AspNetCore.Mvc.Filters;  
        using Microsoft.AspNetCore.Routing;  
        using Core.Logging;  
        /// <summary>  
        /// This is tog every action activity  
        /// </summary>  
        /// <seealso cref="Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute" />  
        [AttributeUsage(AttributeTargets.Class)]  
        public class LogActionFilterAttribute: ActionFilterAttribute {  
            private readonly ILogger logger;  
            /// <summary>  
            /// Initializes a new instance of the <see cref="LogActionFilterAttribute" /> class.  
            /// </summary>  
            /// <param name="logger">The logger.</param>  
            public LogActionFilterAttribute(ILogger logger) {  
                this.logger = logger;  
            }  
            /// <summary>  
            /// Called when [action executing].  
            /// </summary>  
            /// <param name="context">The filter context.</param>  
            public override void OnActionExecuting(ActionExecutingContext context) {  
                this.Log("OnActionExecuting", context.RouteData);  
                base.OnActionExecuting(context);  
            }  
            /// <summary>  
            /// Called when [action executed].  
            /// </summary>  
            /// <param name="context"></param>  
            /// <inheritdoc />  
            public override void OnActionExecuted(ActionExecutedContext context) {  
                this.Log("OnActionExecuted", context.RouteData);  
                base.OnActionExecuted(context);  
            }  
            /// <summary>  
            /// Called when [result executing].  
            /// </summary>  
            /// <param name="context">The filter context.</param>  
            public override void OnResultExecuting(ResultExecutingContext context) {  
                this.Log("OnResultExecuting", context.RouteData);  
                base.OnResultExecuting(context);  
            }  
            /// <summary>  
            /// Called when [result executed].  
            /// </summary>  
            /// <param name="context">The filter context.</param>  
            public override void OnResultExecuted(ResultExecutedContext context) {  
                this.Log("OnResultExecuted", context.RouteData);  
                base.OnResultExecuted(context);  
            }  
            /// <summary>  
            /// Logs the specified method name.  
            /// </summary>  
            /// <param name="methodName">Name of the method.</param>  
            /// <param name="routeData">The route data.</param>  
            private void Log(string methodName, RouteData routeData) {  
                var controllerName = routeData.Values["controller"];  
                var actionName = routeData.Values["action"];  
                string message = $ "MethodName :{methodName} , controller:{controllerName} , action:{actionName}";  
                this.logger.log(message);  
            }  
        }  
    }  

How to make any controller to use this action filter:

Method 1
If you want the functionality to enable for all controllers by default

In starup.cs write the below line:
services.AddMvc(options =>  

options.Filters.Add(typeof(LogActionFilterAttribute));  

});  

Method 2
If you want to use it in Controller specifically:

In starup.cs write the below line:
services.AddScoped<LogActionFilterAttribute>();    

In Action Method or controller use the below attribute:
[ServiceFilter(typeof(ExampleFilterWithDI))]  



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Stars Rating System in ASP.NET Core MVC with Dapper

clock January 30, 2024 07:14 by author Peter

The construction of ASP.NET Core MVC web applications using controllers and views is covered in this lesson. There are various phases involved in implementing a star rating system using Dapper in.NET Core. To save ratings, you must first configure your database schema. Next, in order to communicate with the database, you'll need to establish the Dapper repository and the required model classes.

What is Rate Yo?
Rate Yo is a free, tiny, and flexible jQuery star rating plugin, it uses SVG to generate an image and render rating, so no images are required.

Prerequisites

  • Visual Studio is the latest version with the ASP.NET and web development workload.
  • .NET SDK latest version (.NET 8.0)
  • SQL SERVER latest

Making a table in a database
Start SQL Server, choose Database, then click Create New Database.

CREATE TABLE [dbo].[t_company_rating]
(
    [f_uid]              UNIQUEIDENTIFIER PRIMARY KEY NOT NULL,
    [f_iid]              INT              IDENTITY (1, 1) NOT NULL,
    [f_company_name]     NVARCHAR (100)   NULL,
    [f_company_location] NVARCHAR (100)   NULL,
    [f_country]          NVARCHAR (100)   NULL,
    [f_glassdoor_rating] FLOAT (53)       NULL,
)

Starting a New Visual Studio Project
Open Visual Studio, then choose File > New Project.


Make a Web Application

  • Launch Visual Studio, then choose File > New Project
  • Select the ASP.NET Core Web App (Model-View-Controller) > Next option from the Create a new project dialog box

Setting Up Your New Project
Enter RatingSystem_Demo as the project name in the Configure your new project dialog.

  • The project should be named RatingSystem_Demo. When copying code, capitalization must match each namespace.
  • Select a place to work on your project.
  • Name the solution.
  • Click on Next.

Additional information
In the Additional information dialog.

  • Select .NET 8.0 (Long Term Support).
  • Verify that Do not use top-level statements is unchecked.
  • Select Create.

Option 1. Install the Dapper, Microsoft.Data.SqlClient Library through NuGet Package Manager

  • Go to Project > Manage NuGet Packages.
  • On the NuGet Package Manager page, select nuget.org as the Package source.
  • Under the Browse tab, search for Dapper, then choose Dapper from the list and select Install.
  • If prompted to verify the installation, click OK.

Option 2: Using the Visual Studio Command Line to install the Dapper Library
Go to Tools > NuGet Package Manager > Package Manager Console in Visual Studio.
Under the Package Manager Console tab, type the following command.
Install-Package Dapper

Add RateYo library files

Library files can be added to an ASP.NET Core project in two different ways.

  • Use the Add Client-Side Library dialog
  • Manually configure LibMan manifest file entries

Use the Add Client-Side Library dialog
Follow these steps to install a client-side library.
In Solution Explorer, right-click the project folder in which the files should be added. Choose Add > Client-Side Library. The Add Client-Side Library dialog appears.

Add Client-side Library

The suggested Target Location folder is based on the location from which the dialog is launched.
If launched from the project root.

  • wwwroot/lib is used if wwwroot exists.
  • lib is used if wwwroot doesn't exist.
  • If launched from a project folder, the corresponding folder name is used.

The folder suggestion is suffixed with the library name. The following table illustrates folder suggestions when installing jQuery in a Razor Pages project.

Click the Install button to download the files, per the configuration in libman.json.

Add a data model class

Right-click the Models folder > Add > Class. Name the file CompanyModel.cs.
Replace the Models/CompanyModel.cs file with using c# following code.
The CompanyModel class contains a f_uid field, which is required by the database for the primary key.

CompanyModel.cs
using System.ComponentModel.DataAnnotations;

namespace RatingSystem_Demo.Models
{
    public class CompanyModel
    {
        public Guid f_uid { get; set; }

        [Display(Name ="ID")]
        public int f_iid { get; set; }

        [Display(Name = "Company Name")]
        public string f_company_name { get; set; }

        [Display(Name = "Location")]
        public string f_company_location { get; set; }

        [Display(Name = "Country")]
        public string f_country { get; set; }

        [Display(Name = "Glassdoor Rating")]
        public float f_glassdoor_rating { get; set; }
    }
}


Adding interfaces

  • In Solution Explorer, right-click Add New Folder.
  • Rename the folder to Repositories.
  • Right-click on the renamed folder and Add the interface name IGenericRepository.cs

IGenericRepository.cs
namespace RatingSystem_Demo.Repositories
{
    public interface IGenericRepository<T> where T : class
    {
        Task<IEnumerable<T>> Get();
        Task<T> Find(Guid uid);
        Task<T> Add(T model);
        Task<T> Update(T model);
        Task<T> Remove(T model);
    }
}


IUnitOfWork.cs
namespace RatingSystem_Demo.Repositories
{
    public interface IUnitOfWork
    {
        ICompany Companies { get; }
    }
}

ICompany.cs
using RatingSystem_Demo.Models;

namespace RatingSystem_Demo.Repositories
{
    public interface ICompany:IGenericRepository<CompanyModel>
    {

    }
}


Interface Implementation
UnitOfWork.cs
namespace RatingSystem_Demo.Repositories
{
    public class UnitOfWork : IUnitOfWork
    {
        public ICompany Companies { get; set; }
        public UnitOfWork(ICompany Companies)
        {
            this.Companies = Companies;
        }
    }
}

CompanyRepository.cs
using Dapper;
using Microsoft.Data.SqlClient;
using RatingSystem_Demo.Models;

namespace RatingSystem_Demo.Repositories
{
    public class CompanyRepository : ICompany
    {
        private readonly IConfiguration _configuration;
        private readonly SqlConnection _connection;
        public CompanyRepository(IConfiguration configuration)
        {
            _configuration = configuration;
            _connection = new SqlConnection(_configuration.GetConnectionString("DefaultConnection"));
        }
        public async Task<IEnumerable<CompanyModel>> Get()
        {
            var sql = $@"
                        SELECT [f_uid]
                              ,[f_iid]
                              ,[f_company_name]
                              ,[f_company_location]
                              ,[f_country]
                              ,[f_glassdoor_rating]
                          FROM
                               [Sample-DB].[dbo].[t_company_rating]
                               ORDER BY f_iid ASC";

            return await _connection.QueryAsync<CompanyModel>(sql);
        }
        public async Task<CompanyModel> Find(Guid uid)
        {
            var sql = $@"
                        SELECT [f_uid]
                              ,[f_iid]
                              ,[f_company_name]
                              ,[f_company_location]
                              ,[f_country]
                              ,[f_glassdoor_rating]
                          FROM [Sample-DB].[dbo].[t_company_rating]
                          WHERE
                               [f_uid]=@uid";

            return await _connection.QueryFirstOrDefaultAsync<CompanyModel>(sql, new { uid });
        }
        public async Task<CompanyModel> Add(CompanyModel model)
        {
            model.f_uid = Guid.NewGuid();

            var sql = $@"
                     INSERT INTO [dbo].[t_company_rating]
                           ([f_uid]
                           ,[f_company_name]
                           ,[f_company_location]
                           ,[f_country]
                           ,[f_glassdoor_rating])
                     VALUES
                           (@f_uid,
                            @f_company_name,
                            @f_company_location,
                            @f_country,
                            @f_glassdoor_rating)";

            await _connection.ExecuteAsync(sql, model);
            return model;
        }
        public async Task<CompanyModel> Update(CompanyModel model)
        {
            var sql = $@"UPDATE [dbo].[t_company_rating]
                        SET
                            [f_company_name] = @f_company_name,
                            [f_company_location] = @f_company_location,
                            [f_country] = @f_country,
                            [f_glassdoor_rating] = @f_glassdoor_rating
                         WHERE
                            f_uid=@f_uid";

            await _connection.ExecuteAsync(sql, model);
            return model;
        }
        public async Task<CompanyModel> Remove(CompanyModel model)
        {
            var sql = $@"
                        DELETE FROM
                            [dbo].[t_company_rating]
                        WHERE
                            [f_uid]=@f_uid";

            await _connection.ExecuteAsync(sql, model);
            return model;
        }
    }
}

Add a controller

  • In Solution Explorer, right-click Controllers > Add > Controller.
  • In the Add New Scaffolded Item dialog box, select MVC Controller - Empty > Add.
  • In the Add New Item - RatingSystem_Demo dialog, enter CompaniesController.cs and select Add.

Replace the contents of Controllers/CompaniesController.cs with the following code.
using Microsoft.AspNetCore.Mvc;
using RatingSystem_Demo.Models;
using RatingSystem_Demo.Repositories;

namespace RatingSystem_Demo.Controllers
{
    public class CompaniesController : Controller
    {
        private readonly IUnitOfWork unitOfWork;
        public CompaniesController(IUnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }
        public async Task<IActionResult> Index()
        {
            var companies = await unitOfWork.Companies.Get();
            var ratings = companies.Select(x => x.f_glassdoor_rating).ToList();
            ViewBag.Ratings = string.Join(", ", ratings);
            return View(companies);
        }
        public async Task<IActionResult> Details(Guid id)
        {
            var company = await unitOfWork.Companies.Find(id);
            return View(company);
        }

        public IActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(CompanyModel model)
        {
            var company = await unitOfWork.Companies.Add(model);
            return RedirectToAction(nameof(Index));
        }

        [HttpGet]
        public async Task<IActionResult> Edit(Guid id)
        {
            if (id == Guid.Empty)
            {
                return NotFound();
            }
            var company = await unitOfWork.Companies.Find(id);
            if (company == null)
            {
                return BadRequest();
            }
            return View(company);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(Guid id, CompanyModel model)
        {
            if (id == Guid.Empty)
            {
                return NotFound();
            }
            var company = await unitOfWork.Companies.Find(id);
            if (company == null)
            {
                return BadRequest();
            }
            await unitOfWork.Companies.Update(model);
            return RedirectToAction(nameof(Index));
        }
        public async Task<IActionResult> Delete(Guid id)
        {
            if (id == Guid.Empty)
            {
                return NotFound();
            }
            var company = await unitOfWork.Companies.Find(id);
            if (company == null)
            {
                return BadRequest();
            }
            return View(company);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> ConfirmDelete(Guid id)
        {
            var company = await unitOfWork.Companies.Find(id);
            await unitOfWork.Companies.Remove(company);
            return RedirectToAction(nameof(Index));
        }
    }
}


Add a view

  • Right-click on the Views folder, then Add > New Folder, and name the folder Companies
  • Right-click on the Views/Companies folder, and then Add > New Item.
  • In the Add New Item dialog, select Show All Templates.
  • In the Add New Item - RatingSystem_Demo dialog:
  • In the search box in the upper-right, enter the view
  • Select Razor View - Empty
  • Keep the Name box value, Index.cshtml.
  • Select Add

Replace the contents of the Views/Companies/Index.cshtml, Create.cshtml, Edit.cshtml and Delete.cshtml Razor view file with the following:

Index.cshtml
@model IEnumerable<RatingSystem_Demo.Models.CompanyModel>

@{
    ViewData["Title"] = "Index";
}

<h4 class="text-uppercase text-center">List of companies</h4>

<p style="float:right"><a asp-action="Create" class="btn btn-primary btn-md rounded-0"><i class="fa-solid fa-plus"></i> Add New</a></p>
<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.f_iid)</th>
            <th>@Html.DisplayNameFor(model => model.f_company_name)</th>
            <th>@Html.DisplayNameFor(model => model.f_company_location)</th>
            <th>@Html.DisplayNameFor(model => model.f_country)</th>
            <th>@Html.DisplayNameFor(model => model.f_glassdoor_rating)</th>
            <th>Action(s)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model) {
        <tr>
            <td>@item.f_iid</td>
            <td><a style="text-decoration:none" href="@Url.Action("Details","Companies", new { id = item.f_uid })">@item.f_company_name</a></td>
            <td>@item.f_company_location</td>
            <td>@item.f_country</td>
            <td>
                <span style="float:left;display:inline">@item.f_glassdoor_rating <span style="float:left;display:inline" class="rateYo"></span></span>
            <td>
                <a href="@Url.Action("Edit","Companies", new { id = item.f_uid })" class="btn btn-info btn-sm rounded-0"><i class="fa-solid fa-pen-to-square"></i></a>
                <a href="@Url.Action("Delete","Companies", new { id = item.f_uid })" class="btn btn-danger btn-sm rounded-0"><i class="fa-solid fa-trash"></i></a>
            </td>
        </tr>
}
    </tbody>
</table>
@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
    <script type="text/javascript">
        $(function () {
             var demoRatings = [@ViewBag.Ratings],
            stars = $('.rateYo');
            for (var i = 0; i < stars.length; i++) {
                $('.rateYo').eq(i).rateYo({
                    rating: demoRatings[i],
                    readOnly: true
                });
            }
        });
    </script>
}

Create.cshtml
@model RatingSystem_Demo.Models.CompanyModel

@{
    ViewData["Title"] = "Create";
}
<div class="container">
    <div class="card">
        <div class="card-header">
            <h4>Compnay</h4>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-md-4">
                    <form asp-action="Create">
                        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                        <div class="form-group">
                            <label asp-for="f_company_name" class="control-label"></label>
                            <input asp-for="f_company_name" class="form-control" />
                            <span asp-validation-for="f_company_name" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="f_company_location" class="control-label"></label>
                            <input asp-for="f_company_location" class="form-control" />
                            <span asp-validation-for="f_company_location" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="f_country" class="control-label"></label>
                            <input asp-for="f_country" class="form-control" />
                            <span asp-validation-for="f_country" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="f_glassdoor_rating" class="control-label"></label>
                            <input asp-for="f_glassdoor_rating" readonly class="form-control counter" />
                            <br />
                            <div id="rateYo"></div>
                            <br />
                            <span asp-validation-for="f_glassdoor_rating" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <input type="submit" value="Save" class="btn btn-primary btn-md rounded-0" />
                            <a asp-action="Index" class="btn btn-primary btn-md rounded-0"><i class="fa-solid fa-backward"></i>Back to List </a>
                        </div>
                    </form>
                </div>
            </div>
        </div>
     </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script>
        $(function () {
            $("#rateYo").rateYo({
                onChange: function (rating, rateYoInstance) {
                    $("#f_glassdoor_rating").val(rating);
                }
            });
        });
    </script>
}

Edit.cshtml
@model RatingSystem_Demo.Models.CompanyModel

@{
    ViewData["Title"] = "Edit";
}

<div class="container">
    <div class="card">
        <div class="card-header">
            <h4>Compnay</h4>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-md-4">
                    <form asp-action="Edit">
                        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                        <input hidden asp-for="f_uid" />
                        <input hidden asp-for="f_iid" />
                        <div class="form-group">
                            <label asp-for="f_company_name" class="control-label"></label>
                            <input asp-for="f_company_name" class="form-control" />
                            <span asp-validation-for="f_company_name" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="f_company_location" class="control-label"></label>
                            <input asp-for="f_company_location" class="form-control" />
                            <span asp-validation-for="f_company_location" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="f_country" class="control-label"></label>
                            <input asp-for="f_country" class="form-control" />
                            <span asp-validation-for="f_country" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="f_glassdoor_rating" class="control-label"></label>
                            <input asp-for="f_glassdoor_rating" readonly class="form-control counter" />
                            <br />
                            <div id="rateYo"></div>
                            <br />
                            <span asp-validation-for="f_glassdoor_rating" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <input type="submit" value="Save" class="btn btn-primary btn-md rounded-0" />
                            <a asp-action="Index" class="btn btn-primary btn-md rounded-0"><i class="fa-solid fa-backward"></i>Back to List </a>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
    <script>
        $(function () {
            $("#rateYo").rateYo({
                rating: @Model.f_glassdoor_rating,
                onChange: function (rating, rateYoInstance) {
                    $("#f_glassdoor_rating").val(rating);
                }
            });
        });
    </script>
}


Delete.cshtml
@model RatingSystem_Demo.Models.CompanyModel

@{
    ViewData["Title"] = "Delete";
}

<div class="container">
    <div class="card">
        <div class="card-header">
            <h4>Compnay</h4>
        </div>
        <div class="card-body">
            <h5 class="alert alert-danger" role="alert">Are you sure you want to delete this?</h5>
            <dl class="row">
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(model => model.f_iid)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(model => model.f_iid)
                </dd>
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(model => model.f_company_name)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(model => model.f_company_name)
                </dd>
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(model => model.f_company_location)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(model => model.f_company_location)
                </dd>
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(model => model.f_country)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(model => model.f_country)
                </dd>
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(model => model.f_glassdoor_rating)
                </dt>
                <dd class="col-sm-10">
                    <div id="rateYo"></div>
                </dd>
            </dl>
        </div>
        <div class="card-footer">
            <form asp-action="Delete">
                <button type="submit" class="btn btn-danger btn-sm rounded-0"><i class="fa-solid fa-trash"></i></button>
                <a asp-action="Index" class="btn btn-primary btn-sm rounded-0"><i class="fa-solid fa-backward"></i></a>
            </form>
        </div>
    </div>
</div>
@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
    <script>
        $(function () {
            $("#rateYo").rateYo({
                rating: @Model.f_glassdoor_rating,
                readOnly: true
            });
        });
    </script>
}


Add repository services to the Program.cs
The object get method handles for example the task of connecting to the database and mapping Speaker objects to database records.
The database context get method is registered with the Dependency Injection container using the C# method, for example, the Program.cs file.
builder.Services.AddTransient<ICompany, CompanyRepository>();
builder.Services.AddTransient<IUnitOfWork, UnitOfWork>()

C#
Add Connection String

The ASP.NET Core Configuration system reads the DefaultConnection key. For local development, it gets the connection string from the appsettings.json file.

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=farhan1086\\SQLEXPRESS;Initial Catalog=Sample-DB;Integrated Security=True;MultipleActiveResultSets=True;Encrypt=False;TrustServerCertificate=False;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Run the Application
Select Ctrl+F5 to run the app without the debugger. Visual Studio runs the ASP.NET app and opens the default browser.




ASP.NET MVC Hosting - HostForLIFEASP.NET :: ASP.NET MVC Model Binding with Data Annotations

clock January 17, 2024 07:27 by author Peter

ASP.NET MVC enables developers to link server-side models and user interface elements with ease in the dynamic world of web development. In this process, model binding is essential, and data annotations offer a potent toolkit for specifying metadata about the features of the model. This blog offers a thorough how-to for ASP.NET MVC newcomers, with the goal of demystifying the relationship between model binding and data annotations.

The Model-View-Controller architectural pattern, which is used by ASP.NET MVC, has views handle display while controllers handle user input and coordinate interactions between views and models. Models contain data and business logic. The process by which user input from a form or other sources is used to populate the model properties is known as model binding.

On the other side, characteristics added to model properties to provide metadata about how they should be handled during model binding, validation, and rendering are known as data annotations.

Model Binding Basics
Consider a simple scenario where you have a Person model.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

It may be desirable to connect user input to this model in a controller action.

[HttpPost]
public ActionResult SavePerson(Person person)
{
    // Process the person object
    // ...
}

Introducing Data Annotations
Now, let's enhance the Person model with data annotations to provide more information to the model binder.
public class Person
{
    [Required(ErrorMessage = "First Name is required")]
    [StringLength(50, ErrorMessage = "First Name should be less than 50 characters")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Last Name is required")]
    [StringLength(50, ErrorMessage = "Last Name should be less than 50 characters")]
    public string LastName { get; set; }

    [Range(1, 150, ErrorMessage = "Age should be between 1 and 150")]
    public int Age { get; set; }
}

Important Data Annotations Employed

  • Indicates that a certain attribute is necessary.
  • StringLength: Indicates a string property's maximum length.
  • Range: Indicates a numeric property's value range.

Making the Most of Data Annotations in Views

@using (Html.BeginForm("SavePerson", "YourController", FormMethod.Post))
{
    @Html.LabelFor(model => model.FirstName)
    @Html.TextBoxFor(model => model.FirstName)
    @Html.ValidationMessageFor(model => model.FirstName)

    // Repeat for LastName and Age properties

    <input type="submit" value="Save" />
}

Important HTML Helpers Employed

  • The label element for a model attribute is rendered by LabelFor.
  • Renders a text input element for a model attribute using TextBoxFor.
  • ValidationMessageFor: Validation error messages for a model property rendered by the renderer.

In-Progress Model Validation
The model binder automatically validates the user input when the form is submitted by using the data annotations. Error notifications appear next to the respective form fields if any validation fails.

HTML helpers can be used to render form components in a view. Annotations on data affect the generation and validation of these elements.

Data Annotations' Advantages in Model Binding
Consistency: Data annotations offer a declarative and consistent means of defining validation criteria, guaranteeing consistency throughout the program.
Readability: Developers can readily comprehend the limitations and specifications of each property since validation rules are incorporated directly into the model.
Reuse: Data annotations facilitate code reuse by allowing the same model to be applied with identical validation rules across contexts.

Validating form data and processing user input are made easier using ASP.NET MVC model binding and data annotations. Developers can define validation criteria succinctly within the model itself by utilizing properties like Required, StringLength, and Range. This method makes code more readable, encourages consistency, and makes it easier to maintain reliable and user-friendly online applications. Embrace the power of model binding and data annotations as you begin your ASP.NET MVC adventure to build applications that are robust and user-friendly.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Security ASP.net Core MVC (C#) Encryption and Decryption

clock September 20, 2023 07:27 by author Peter

Harnessing the power of C# to enhance our data security through encryption and decryption is a versatile and necessary feature in the world of ASP.NET Core MVC. This security boost is made possible by the use of a variety of encryption methods, including but not limited to AES (Advanced Encryption Standard), RSA (Rivest-Shamir-Adleman), DES (Data Encryption Standard), and others. These cryptographic algorithms enable developers to protect sensitive information while keeping it secure and tamper-resistant.

Let's look at how the AES algorithm, recognized for its strong encryption capabilities, may be smoothly integrated into our ASP.NET Core MVC application to encrypt and decrypt data. This example provides a baseline understanding of encryption processes within the ASP.NET Core MVC framework, allowing developers to begin exploring and implementing sophisticated security features in their web applications.

We'll have a better understanding of how to use the AES algorithm in our ASP.NET Core MVC projects by the end of this demonstration, enhancing our capacity to secure and protect key data assets. This knowledge enables us to make informed judgments about which encryption approaches best suit our application's particular security requirements, assuring the highest level of protection for our users' sensitive data.

Step 1: Create an Encryption/Decryption Helper Class.
To carry out encryption and decryption operations within our program, it is generally advised that we construct a specialized helper class. Here's an example of a well-structured class that can be utilized to improve the security of our application.

using System.Security.Cryptography;

namespace ZR.CodeExample.SecureMVC.Helpers
{
    public static class EncryptionHelper
    {
        private static readonly string EncryptionKey = GenerateRandomKey(256);

        public static string Encrypt(string plainText)
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Convert.FromBase64String(EncryptionKey);
                aesAlg.IV = GenerateRandomIV(); // Generate a random IV for each encryption

                aesAlg.Padding = PaddingMode.PKCS7; // Set the padding mode to PKCS7

                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                    }
                    return Convert.ToBase64String(aesAlg.IV.Concat(msEncrypt.ToArray()).ToArray());
                }
            }
        }


        public static string Decrypt(string cipherText)
        {
            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Convert.FromBase64String(EncryptionKey);
                aesAlg.IV = cipherBytes.Take(16).ToArray();

                aesAlg.Padding = PaddingMode.PKCS7; // Set the padding mode to PKCS7

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msDecrypt = new MemoryStream(cipherBytes, 16, cipherBytes.Length - 16))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            return srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
        }

        private static byte[] GenerateRandomIV()
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.GenerateIV();
                return aesAlg.IV;
            }
        }

        private static string GenerateRandomKey(int keySizeInBits)
        {
            // Convert the key size to bytes
            int keySizeInBytes = keySizeInBits / 8;

            // Create a byte array to hold the random key
            byte[] keyBytes = new byte[keySizeInBytes];

            // Use a cryptographic random number generator to fill the byte array
            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(keyBytes);
            }

            // Convert the byte array to a base64-encoded string for storage
            return Convert.ToBase64String(keyBytes);
        }

    }
}

This helper class contains the encryption and decryption functionality, as the name implies, making it easy to secure sensitive data in our ASP.NET Core MVC application. As part of best practices, we produce the encryption key dynamically. GenerateRandomKey(256)

We improve the security of our application by isolating the encryption and decryption code in a dedicated helper class. This method enables us to quickly handle sensitive data within our ASP.NET Core MVC application, adding an additional degree of security.

Step 2: Encryption and decryption are used in our controller or service
To use the encryption and decryption capabilities we've incorporated, we'll need to call the Encrypt and Decrypt methods within our controller or service class. Here's a detailed example on how to accomplish it.

using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ZR.CodeExample.SecureMVC.Helpers;
using ZR.CodeExample.SecureMVC.Models;

namespace ZR.CodeExample.SecureMVC.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            // Define the data you want to secure
            string plainText = "I am Peter from United Kingdom";

            // Encrypt the data using the EncryptionHelper
            string cipherText = EncryptionHelper.Encrypt(plainText);

            // Decrypt the data to retrieve the original content
            string decryptedText = EncryptionHelper.Decrypt(cipherText);

            // Store the encrypted and decrypted data in ViewData for use in your view
            ViewData["CipherText"] = cipherText;
            ViewData["DecryptedText"] = decryptedText;

            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

Step 3: In the View, show both encrypted and decrypted data
One of the most impressive characteristics of Razor views is their ability to display both encrypted and decrypted data from our controller's ViewData dictionary. We can successfully provide sensitive information to our users in a secure manner by exploiting this feature. Let's look at an example of how this can be done within a Razor view.

@{
    ViewData["Title"] = "Security ASP.net Core MVC (C#) Encryption and Decryption";
}

<div class="text-center">
    <h1 class="display-4">@ViewData["Title"]</h1>
    <p>By Peter, delve into the intricacies of security in ASP.NET Core MVC (C#) through our comprehensive article, focusing on the vital aspects of encryption and decryption techniques. Learn how to safeguard your web applications effectively.</p>
</div>
<div>
    <h2>Encrypted Text:</h2>
    <p>@ViewData["CipherText"]</p>
</div>

<div>
    <h2>Decrypted Text:</h2>
    <p>@ViewData["DecryptedText"]</p>
</div>
<div>
    <h3>Who is Peter</h3>
    <p>I am 
Peter, a seasoned Technical Lead Developer </p>
</div>

We'll suppose in this code snippet that our controller action is coupled with a view, such as Index.cshtml. We may display the encrypted and decrypted content on the web page by using this Razor view. Furthermore, we have the ability to modify the HTML structure and styling to match the design and requirements of our application.




About HostForLIFE

HostForLIFE 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 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in