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 :: 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.




ASP.NET MVC Hosting - HostForLIFEASP.NET :: A Simple Architecture for Developing Web Applications Using ASP.NET Core MVC C#

clock September 14, 2023 06:59 by author Peter

When paired with the Clean Architecture pattern, ASP.NET Core MVC provides a solid framework for building online applications that can result in controllable and extendable solutions. In this article, we will look at how to organize an ASP.NET Core MVC project utilizing Clean Architecture principles, using C# code samples.

What is the Clean Architecture Concept?
Clean Architecture is a software design philosophy that emphasizes concern separation and maintainability by layering the codebase. Typically, these layers include.

Layer of User Interface
The presentation elements are placed here. It includes controllers, views, and view models in the context of ASP.NET Core MVC.

Layer of Application
This layer contains the application's business logic. It is in charge of managing user queries, data processing, and interfacing with the domain layer.

The Domain Layer
This layer is the application's heart, defining the fundamental business entities, rules, and domain-specific logic. It must be decoupled from any infrastructure or application-specific code.

Layer of Infrastructure
This layer handles external concerns like data access, external services, and infrastructure-related code. It should be kept separate from the other layers.

Establishing a Clean Architecture Initiative
Let's get started by making a new ASP.NET Core MVC project with Clean Architecture in mind.

Step One: Make a New ASP.NET Core MVC Project

To start a new ASP.NET Core MVC project, we can use either the dotnet command-line tool or Visual Studio. Ascertain that the ASP.NET Core SDK is installed.

dotnet new mvc -n ZRCleanArchitectureApp

Step 2: Creating a Project Structure
Separate our project into distinct folders for each layer to better organize it.

ZRCleanArchitectureApp.Web
This folder comprises controllers, views, and view models and represents the presentation layer.

ZRCleanArchitectureApp.Application

We define application services and business logic in this subdirectory.

ZRCleanArchitectureApp.Domain
This folder contains the definitions of our domain entities and business rules.

ZRCleanArchitectureApp.Infrastructure

This section handles data access, external services, and infrastructure-related code.

Step 3: Put Clean Architecture into Practice
Domain Entities Definition

// ZRCleanArchitectureApp.Domain/Entities/Product.cs
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}


Implementing Application Services
// ZRCleanArchitectureApp.Application/Services/ProductService.cs
public class ProductService
{
    private readonly IProductRepository _productRepository;

    public ProductService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    public async Task<IEnumerable<Product>> GetAllProductsAsync()
    {
        return await _productRepository.GetAllAsync();
    }

    // Add other business logic methods here
}


Creating Controllers
// ZRCleanArchitectureApp.Web/Controllers/ProductController.cs
public class ProductController : Controller
{
    private readonly ProductService _productService;

    public ProductController(ProductService productService)
    {
        _productService = productService;
    }

    public async Task<IActionResult> Index()
    {
        var products = await _productService.GetAllProductsAsync();
        return View(products);
    }

    // Add other action methods
}


Configuring Dependency Injection
In the Program.cs file, configure dependency injection for our services and repositories.
builder.Services.AddScoped<ProductService>();
builder.Services.AddScoped<IProductRepository, ProductRepository>();

ASP.NET Core MVC Clean Architecture provides a disciplined approach to designing maintainable, scalable, and easily testable web applications. We may focus on building clean, modular code by dividing concerns into discrete levels.

We have barely scraped the surface of Clean Architecture in this post. We may improve our project by incorporating validation, authentication, and authorization systems, as well as unit tests to check the accuracy of our code.

Keep in mind that Clean Architecture is a suggestion, not a hard and fast rule. Adapt it to our project's unique requirements and complexities, and strive for simplicity and maintainability in our codebase at all times.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: How to Implement Multiselect Checkboxes in ASP.NET MVC Using AJAX?

clock August 4, 2023 07:40 by author Peter

In this tutorial, we will look at how to create a dynamic form with multiselect checkboxes in an ASP.NET MVC application. We'll concentrate on how to use jQuery AJAX to handle form submission, retrieve the selected checkboxes, and store the data to the database. The code provided offers a detailed example of how to develop a user-friendly student data management system that allows each student to select several languages.


You should have a basic understanding of ASP.NET MVC, C#, jQuery, and Entity Framework before going.

How do you make a Multiselect Checkbox Form?

In the "Index.chtml" file, we have designed a form to collect student data, including a section to select multiple languages for each student using checkboxes.
<!-- Index.chtml -->
<!-- ... (existing code) ... -->
<div class="text-light text-center my-3">
    <div class="d-flex justify-content-center">
        <h5 class="text-warning">Languages:</h5>
        <div id="languagesSection">
            @for (int i = 0; i < Model.Languages.Count; i++)
            {
                <label>@Model.Languages[i].LanguageName</label>
                @Html.CheckBoxFor(model => model.Languages[i].IsChecked)
                @Html.HiddenFor(model => model.Languages[i].ID)
                @Html.HiddenFor(model => model.Languages[i].LanguageName)
            }
        </div>
    </div>
</div>
<!-- ... (existing code) ... -->

Implementing AJAX for Adding Data to Database
In the JavaScript section, we've implemented an AJAX function to handle the form submission and add student data to the database.
// AJAX for Adding Data to Database
$("#SumbitButton").click(function () {
    var selected = []; // initialize array
    $('div#languagesSection2 input[type=checkbox]').each(function () {
        if ($(this).is(":checked")) {
            selected.push($(this).attr("id"));
        }
    });

    $("#Languages").val(selected);
    var studentData = $("#studentInputForm").serialize();

    if (!$('#studentInputForm').valid()) {
        return false;
    }

    $.ajax({
        url: "/Home/SaveStudent",
        type: "POST",
        data: studentData,
        success: function (data) {
            $('#studentInputForm').find(':input').val('');
            $('input[type=checkbox]').prop('checked', false);
        },
        error: function (errormessage) {
            console.log("error message");
        }
    });
});

Handling the AJAX Request in the Controller
In the "HomeController," we've added two action methods, one for saving student data and the other for handling the edit functionality.
public class HomeController : Controller
{
    OperationRepositery repo = null;
    public HomeController()
    {
        repo = new OperationRepositery();
    }

    public ActionResult Index()
        {
            StudentModel model = new StudentModel();
            model.Languages = db.LanguagesTable.Select(lang => new LanguagesModel
            {
                ID = lang.ID,
                LanguageName = lang.LanguagesName,
            }).ToList();
            return View(model);
        }

    // Action method for adding student data
    public ActionResult SaveStudent(StudentModel model)
    {
        var result = repo.AddData(model);
        return Json(new { result = true }, JsonRequestBehavior.AllowGet);
    }

    // Action method for handling the edit functionality
    public ActionResult EditStudent(int ID)
    {
        var result = repo.EditFunction(ID);
        var languageIdList = result.LanguageIds.Split(',').Select(x => Convert.ToInt32(x)).ToList();
        result.Languages = db.LanguagesTable.Select(x => new LanguagesModel
        {
            ID = x.ID,
            LanguageName = x.LanguagesName,
            IsChecked = languageIdList.Contains(x.ID)
        }).ToList();
        return View(result);
    }
}


Happy coding!



ASP.NET MVC Hosting - HostForLIFEASP.NET :: How to Implement Multiselect Checkboxes in ASP.NET MVC Using AJAX?

clock August 4, 2023 07:17 by author Peter

We will explore how to implement a dynamic form with multiselect checkboxes in an ASP.NET MVC application. We'll focus on using jQuery AJAX to handle the form submission, retrieve the selected checkboxes, and save the data to the database. The provided code includes a complete example of how to create a user-friendly student data management system with the ability to select multiple languages for each student.


Before proceeding, you should have a basic understanding of ASP.NET MVC, C#, jQuery, and Entity Framework.
How to create the Multiselect Checkbox Form?

In the "Index.chtml" file, we have designed a form to collect student data, including a section to select multiple languages for each student using checkboxes.
<!-- Index.chtml -->
<!-- ... (existing code) ... -->
<div class="text-light text-center my-3">
    <div class="d-flex justify-content-center">
        <h5 class="text-warning">Languages:</h5>
        <div id="languagesSection">
            @for (int i = 0; i < Model.Languages.Count; i++)
            {
                <label>@Model.Languages[i].LanguageName</label>
                @Html.CheckBoxFor(model => model.Languages[i].IsChecked)
                @Html.HiddenFor(model => model.Languages[i].ID)
                @Html.HiddenFor(model => model.Languages[i].LanguageName)
            }
        </div>
    </div>
</div>
<!-- ... (existing code) ... -->

Implementing AJAX for Adding Data to Database
In the JavaScript section, we've implemented an AJAX function to handle the form submission and add student data to the database.
// AJAX for Adding Data to Database
$("#SumbitButton").click(function () {
    var selected = []; // initialize array
    $('div#languagesSection2 input[type=checkbox]').each(function () {
        if ($(this).is(":checked")) {
            selected.push($(this).attr("id"));
        }
    });

    $("#Languages").val(selected);
    var studentData = $("#studentInputForm").serialize();

    if (!$('#studentInputForm').valid()) {
        return false;
    }

    $.ajax({
        url: "/Home/SaveStudent",
        type: "POST",
        data: studentData,
        success: function (data) {
            $('#studentInputForm').find(':input').val('');
            $('input[type=checkbox]').prop('checked', false);
        },
        error: function (errormessage) {
            console.log("error message");
        }
    });
});

Handling the AJAX Request in the Controller
In the "HomeController," we've added two action methods, one for saving student data and the other for handling the edit functionality.
public class HomeController : Controller
{
    OperationRepositery repo = null;
    public HomeController()
    {
        repo = new OperationRepositery();
    }

    public ActionResult Index()
        {
            StudentModel model = new StudentModel();
            model.Languages = db.LanguagesTable.Select(lang => new LanguagesModel
            {
                ID = lang.ID,
                LanguageName = lang.LanguagesName,
            }).ToList();
            return View(model);
        }

    // Action method for adding student data
    public ActionResult SaveStudent(StudentModel model)
    {
        var result = repo.AddData(model);
        return Json(new { result = true }, JsonRequestBehavior.AllowGet);
    }

    // Action method for handling the edit functionality
    public ActionResult EditStudent(int ID)
    {
        var result = repo.EditFunction(ID);
        var languageIdList = result.LanguageIds.Split(',').Select(x => Convert.ToInt32(x)).ToList();
        result.Languages = db.LanguagesTable.Select(x => new LanguagesModel
        {
            ID = x.ID,
            LanguageName = x.LanguagesName,
            IsChecked = languageIdList.Contains(x.ID)
        }).ToList();
        return View(result);
    }
}


Happy coding!



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.


Tag cloud

Sign in