European ASP.NET MVC 4 and MVC 5 Hosting

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

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

clock March 26, 2025 08:41 by author Peter

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

Open our solution MVCTestApplication, given below:

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

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

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

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

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

 

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

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

 

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

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

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

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

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

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

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

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

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

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

Just write this line in your web.config file.

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

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

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

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



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

clock March 18, 2025 07:30 by author Peter

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

The Fundamental Concept
Assuming you are working on two projects,

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

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

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

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


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


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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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




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

clock March 13, 2025 09:16 by author Peter

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

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

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

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

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

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

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

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


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

AccountModel.cs class contain following methods.

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

WebSecurity.InitializeDatabaseConnection

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

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

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

Now globel.asax page will look like:

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

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

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


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


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


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

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

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

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

So the code for the Registration action method is:

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


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



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

clock February 10, 2025 07:09 by author Peter

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

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

Introduction
Before starting, ensure you have the following.

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

Step 1. Create a Stripe Account

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

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

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

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

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

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

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

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

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


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

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

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

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

Step 8. Run and Test the Application

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

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

Click the Pay with Stripe Button.


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

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


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

Create a Webhook Endpoint in the Stripe Dashboard.

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

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


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

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



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

clock February 3, 2025 06:14 by author Peter

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

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

Benefits

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

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

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

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

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


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

Benefits

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

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

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

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

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

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


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

Benefits

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

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


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

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

public class ProductsController : Controller
{
    private readonly UnitOfWork _unitOfWork;

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

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

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

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

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

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

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

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

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

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

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

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

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

<h2>Product List</h2>

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

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

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

Benefits

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

Implementation
Factory Implementation

public interface IProductService
{
    void ProcessOrder();
}

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

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

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

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

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

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

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

Benefits

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

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

    private LogManager() { }

    public static LogManager Instance => instance.Value;

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


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

Benefits

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

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

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

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

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

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

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

Output

 



ASP.NET MVC Hosting - HostForLIFE.eu :: Generic Repository Pattern With MVC

clock January 24, 2025 07:21 by author Peter

In this article, I am going to explain the generic repository pattern. We are going to start the concept and implementation of the repository pattern, so first, let's try to understand what it is.


Why go with the repository pattern?

Enterprise applications such as web-based enterprise applications, order management systems, payroll, accounting applications, etc., are large-scale data flow applications. Along with data flow, they have some other features too.

  • Large amount of data: These types (accounting, payroll, order management) of applications handle quite a large amount of data. And this amount of data is not fixed. It may vary day by day and get more and more than the previous day.
  • Separation of database and application: Handling of data for an application is a major undertaking that needs some persistent storage. We usually separate the database engine from the application. The data object is a multiuser environment. At a given point in time, the data should be overwritten and given a concurrency feature.
  • Modification in business rules is always acceptable: Enterprise applications will always have new rules, so our application should be ready to accept those changes without affecting the past code and logic. These rules can change at any time. At the time of business upgrade, our application should be ready to accept all the changes. Sometimes, business rules have operations that usually deal with the size (data) and display the data on many pages or one page, we may have to display the data from different tables.

We come across these scenarios daily and reach one conclusion, that is,

Enterprise applications function in three different areas

  • Data Access: This layer deals with the data storage and retrieval, such as CRUD (Create, Read, Update, Delete)
  • Business Rule: This layer deals with data access such as reading and writing data and encapsulation with business-specific rules
  • User Interface: Displays the data to the end user and also accepts input from the end user.

We use a repository pattern when the scenario is dealing with a complex set of queries from multiple tables, to avoid duplication so that we will not write the same code at multiple places.

In these scenarios, we use a layer between our domain class and the data access layer. This layer will take care of all operations that can be reused again and again. In short, we can say that "Repository pattern plays a mediator's role in between the data-access layer and all the system."

Once the repository pattern is implemented, the client code won’t invoke the data access directly. Instead, we will invoke the repository to get the job done. The repository offers a collection interface by providing methods to add, modify, remove, and fetch domain objects.

Let’s try to implement a generic repository pattern in the ASP MVC application. Before going to the implementation part, it is a very common question usually asked by many developers - Entity Framework is already developed in a repository pattern. Then, why will we again create a repository pattern?

I am trying to answer that.

In a small application, it is not required at all, but in enterprise applications, it is beneficial.

  • Promoting loose coupling: In the repository pattern, all query code is isolated from the Entity Framework objects, so that it gives a good way to implement loose coupling with other model classes.
  • Preventing Entity Framework objects from business logic layers: Giving all data access (Entity Framework objects) to the business layer is not a good idea. All LINQ queries get embedded inside it, these things are not desirable.

Steps to implement generic repository in ASP.NET MVC

Step 1. Add a new MVC template

Choose an MVC template.

Step 2. Add Entity Framework

Step 3. We are going to choose code first approach for creating a database and respective tables.

After defining the model class for students, now, we are now going to make a schema class for the code-first approach.
[Table("Students")]
public class Student
{
    [Key]
    [Display(Name = "Student Id")]
    public int StId { get; set; }

    [Required]
    [Display(Name = "Student Name")]
    public string StName { get; set; }

    [Display(Name = "Address")]
    public string StAddress { get; set; }

    [Required]
    [Display(Name = "Mobile No.")]
    public string MobileNo { get; set; }
}

Step 4. Create studentConext


Step 5. Add database set Initializer
Usually, in Entity Framework, there are four different ways to create an Initializer.

  • CreateDatabaseIfNotExists: This is the default initializer and it will create the database if it does not exist already, as per the configuration. One more thing; it will throw an exception if the model class is changed and will try to run the application with this initializer.
  • DropCreateDatabaseIfModelChanges: According to this initializer, it drops an existing database and creates a new database if model classes (entity classes) are changed.
  • DropCreateDatabaseAlways: According to this initializer, it drops an existing database every time when we run the application. It doesn’t worry about the model class changes. This is useful when we want a fresh database every time we run the application.
  • Customer db Initializer: We can create our own custom initializer.

Syntax
public class SchoolDataBaseInitializer : CreateDatabaseIfNotExists<StudentContext>
{
    protected override void Seed(StudentContext context)
    {
        base.Seed(context);
    }
}


For this application, I am implementing the “DropCreateDatabaseIfModelChanges” database initializer method, globally.aspx file.
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        Database.SetInitializer<StudentContext>(new DropCreateDatabaseIfModelChanges<StudentContext>());
    }
}


Step 6. Now working with Generic Repository
Add an Interface.
public interface IGenericRepo<T> where T : class
{
    IEnumerable<T> GetAll();
    T GetById(int id);
    void Insert(T obj);
    void Update(T obj);
    void Delete(int id);
    void Save();
}


As we can see Interface is very simple and easy to understand here, Here <T> I took to incorporate with any classes whoever needed.
Inside Interface, we are implementing two type parameters - T1, (type parameter is a concept which is taken in C++ for making the generic concept). Here, I am not saying both are the same. The T1 type parameter specifies the class type, which means that we pass the class while implementing the generic interface to any class, and on the other hand, I haven’t specified the T2 with any data, the reason is that - it might be any class having unique id in different type (might be int, string or all).

Implement the generic repository with Entity Framework.
public class GenericRepo<T> : IGenericRepo<T> where T : class
{
    private StudentContext _context = null;
    private DbSet<T> table = null;

    public GenericRepo()
    {
        this._context = new StudentContext();
        table = _context.Set<T>();
    }

    public GenericRepo(StudentContext _context)
    {
        this._context = _context;
        table = _context.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return table.ToList();
    }

    public T GetById(int id)
    {
        return table.Find(id);
    }

    public void Insert(T obj)
    {
        table.Add(obj);
    }

    public void Update(T obj)
    {
        table.Attach(obj);
        _context.Entry(obj).State = EntityState.Modified;
    }

    public void Delete(int id)
    {
        T existing = table.Find(id);
        table.Remove(existing);
    }

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


Now, it is very easy to implement the controller class to play with CRUD operation with the Repository class. As the code stated first we are creating a private member of our context class, and assigning it to null. same as with the Dbset.

Two constructors I created, as default and parameterized for initializing the context. As the context is get initilize we will able to call implemented Generic methods.

Have a look at the fetch and insert records using the Controller class.
public class HomeController : Controller
{
    private IGenericRepo<Students> repository = null;

    public HomeController()
    {
        this.repository = new GenericRepo<Students>();
    }

    public HomeController(IGenericRepo<Students> repository)
    {
        this.repository = repository;
    }

    public ActionResult Index()
    {
        var obj = repository.GetAll();
        return View(obj);
    }

    [HttpGet]
    public ActionResult AddStudent()
    {
        return View();
    }

    [HttpPost]
    public ActionResult AddStudent(Students obj)
    {
        repository.Insert(obj);
        return RedirectToAction("Index");
    }
}

Summary
This article explained the generic repository pattern, this approach where we can handle multiple databases with a single implemented class, only we have to pass the respective class to operate the desired result. We have also seen the pros and cons of the generic repository pattern.



ASP.NET MVC Hosting - HostForLIFE.eu :: Knowing EF Core MVC's Connected Disconnected Scenarios

clock January 7, 2025 06:56 by author Peter

Working with data is essential in contemporary online applications, and Entity Framework Core (EF Core) offers a productive method of interacting with databases through the use of Object-Relational Mapping (ORM). The Connected and Disconnected scenarios are the two main methods that EF Core provides for handling data in an application. Both situations differ in how data is recorded, accessed, and stored in the database, and they are crucial in distinct use cases. Both of these ideas are examined in this article along with workable solutions in a.NET Core MVC application.

What is a Connected Scenario?
In a Connected scenario, the DbContext is directly connected to the entity instances and actively tracks changes made to the data. This is the default behavior of EF Core when entities are retrieved using a context and modified within the scope of the context.

  • Key Characteristics of a Connected Scenario
  • Change Tracking: EF Core automatically tracks changes made to the entities. When SaveChanges() is called, it updates the database with those changes.
  • Short-lived Context: The DbContext instance is created, used, and disposed of within a limited scope, often tied to a single HTTP request in a web application.
  • Automatic State Management: EF Core keeps track of the state of entities, such as Added, Modified, Deleted, and Unchanged.

Practical Example
Let’s create a simple CRUD operation in a Connected scenario for managing a list of users.

Create the Model
namespace EFCoreConnectedDisconnectedDemo.Model
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Email { get; set; }
    }
}

Set Up DbContext
using EFCoreConnectedDisconnectedDemo.Model;
using Microsoft.EntityFrameworkCore;

namespace EFCoreConnectedDisconnectedDemo.ApplicationContext
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

        public DbSet<User> Users { get; set; }
    }
}

Create the controller

using EFCoreConnectedDisconnectedDemo.ApplicationContext;
using EFCoreConnectedDisconnectedDemo.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace EFCoreConnectedDisconnectedDemo.Controllers
{
    public class UserController : Controller
    {
        private readonly ApplicationDbContext _context;

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

        // GET: User
        public IActionResult Index()
        {
            var users = _context.Users.ToList();
            return View(users);
        }

        // GET: User/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: User/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create([Bind("Id, Name, Email")] User user)
        {
            if (ModelState.IsValid)
            {
                _context.Add(user);
                _context.SaveChanges(); // Save the changes in the connected scenario
                return RedirectToAction(nameof(Index));
            }
            return View(user);
        }

        // GET: User/Edit/5
        public IActionResult Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var user = _context.Users.Find(id);
            if (user == null)
            {
                return NotFound();
            }
            return View(user);
        }

        // POST: User/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Edit(int id, [Bind("Id, Name, Email")] User user)
        {
            if (id != user.Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(user);
                    _context.SaveChanges(); // EF Core automatically tracks changes and updates the database
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!_context.Users.Any(e => e.Id == user.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(user);
        }

        // GET: User/Delete/5
        public IActionResult Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var user = _context.Users
                .FirstOrDefault(m => m.Id == id);
            if (user == null)
            {
                return NotFound();
            }

            return View(user);
        }

        // POST: User/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public IActionResult DeleteConfirmed(int id)
        {
            var user = _context.Users.Find(id);
            _context.Users.Remove(user);
            _context.SaveChanges(); // EF Core will automatically track the deletion
            return RedirectToAction(nameof(Index));
        }
    }
}


Create the Views
Index.cshtml, Create.cshtml, Edit.cshtml, and Delete.cshtml are Razor views for handling the respective CRUD actions.

How it Works in a Connected Scenario?

  • Tracking Changes: EF Core tracks changes made to User entities in the database automatically.
  • Saving Changes: Calling SaveChanges() saves the changes (whether added, updated, or deleted) to the database.

What is a Disconnected Scenario?
In a Disconnected scenario, the DbContext is not available to track changes once the data is retrieved from the database. This scenario is common in applications where the DbContext is disposed of after the entity data is fetched, such as in web APIs where entities are transferred over HTTP.

Key Characteristics of a Disconnected Scenario

  • No Change Tracking: Entities are not tracked once the DbContext is disposed of, meaning changes must be manually managed.
  • Manual State Management: In disconnected scenarios, the entity must be explicitly attached to the context and marked with its state (e.g., Modified) when changes are saved.
  • Common in Web APIs: Commonly used in Web API scenarios where entities are transferred to and from clients and must be handled after detaching from the context.

Practical Example
Let’s handle a simple scenario where data is fetched in a disconnected manner, then updated and saved.

Create a Web API Controller for Disconnected Scenario
using EFCoreConnectedDisconnectedDemo.ApplicationContext;
using EFCoreConnectedDisconnectedDemo.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace EFCoreConnectedDisconnectedDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ApiUserController : ControllerBase
    {
        private readonly ApplicationDbContext _context;

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

        // GET: api/ApiUser/5
        [HttpGet("{id}")]
        public ActionResult<User> GetUser(int id)
        {
            var user = _context.Users.Find(id);
            if (user == null)
            {
                return NotFound();
            }
            return user;
        }

        // PUT: api/ApiUser/5
        [HttpPut("{id}")]
        public IActionResult PutUser(int id, User user)
        {
            if (id != user.Id)
            {
                return BadRequest();
            }

            // In disconnected scenario, we must attach the entity back to the context and mark it as modified
            _context.Users.Attach(user);
            _context.Entry(user).State = Microsoft.EntityFrameworkCore.EntityState.Modified;

            try
            {
                _context.SaveChanges(); // Save changes to the database manually
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!_context.Users.Any(e => e.Id == user.Id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }
    }
}


How it Works in a Disconnected Scenario?
The data is fetched and passed to the client (e.g., as JSON).

When the client sends an updated version of the entity, the entity must be explicitly attached to the DbContext.

The entity is marked as modified, and the changes are saved by calling SaveChanges().

When to Use Each Scenario?

  • Connected Scenario: Best suited for web applications or APIs where the DbContext remains active throughout the request lifecycle. It simplifies the development process since EF Core automatically handles change tracking.
  • Disconnected Scenario: Ideal for web APIs and scenarios where the DbContext is not available after data is retrieved. It requires explicit management of entity states and is suitable for distributed systems or client-server models.

Conclusion
In this post, we looked at how to use Entity Framework Core in an ASP.NET Core MVC application to manage connected and disconnected circumstances. Knowing the distinctions between these two methods can help you decide whether your application needs manual state management (disconnected) or automatic change monitoring (connected) for data management. Both situations are necessary for developing effective and reliable data-driven applications and are crucial in various use cases.



ASP.NET MVC Hosting - HostForLIFE.eu :: Action Method In ASP.NET MVC

clock December 20, 2024 08:02 by author Peter

ASP.NET MVC action methods are responsible to execute the request and generate a response to it. All the public methods of the MVC Controller are action methods. If we want the public method to be a  non-action method, then we can decorate the action method by “NonAction” attribute. It will restrict the action method to render on the browser.

 
To work with action method we need to remember the following points.

  • The action method is the public non-static method.
  • Action method can not be the private or protected method.
  • Action method can not contain ref and out parameters.
  • Action method can not be an extension method.
  • Action method can not be overloaded.

Example of an action method in ASP.NET MVC 5 is as below.

    public class HomeController : Controller  
        {  
            // GET: Home  
            public ActionResult Index()  
            {  
                return View();  
            }  
    }  


You can see in the above action method example that the Index() method is a public method which is inside the HomeController class. And the return type of the action method is ActionResult. It can return using the “View()” method. So, every public method inside the Controller is an action method in MVC.
 
Action Method can not be a private or protected method.
    public class HomeController : Controller  
        {  
            // GET: Home  
            private ActionResult Index()  
            {  
                return "This is Index Method";          
            }  
    }  


If you provide the private or protected access modifier to the action method, it will provide the error to the user, i.e., “resource can not be found” as below.

Action method can not be overloaded.
    public string Index()  
           {            
               return "This is Index Method";  
           }  
      
           public string Index(int id)  
           {  
               return "This is Index overloaded Method";  
           }  

If you try to overload the action method, then it will throw an ambiguous error.

An action method cannot contain ref and out parameters.
    public string Index(ref int id)  
            {  
                return "This is Index Method" +id;  
            }  

    public string Index(out int id)  
           {  
               id = 0;  
               return "This is Index Method" +id;  
           }  


We can not provide the ref and out parameters to the action method. If you try to provide the ref and out parameters to the action method, then it will throw an error as below.



Action method can not be overloaded.
    public string Index()  
           {            
               return "This is Index Method";  
           }  
      
           public string Index(int id)  
           {  
               return "This is Index overloaded Method";  
           }  


If you try to overload the action method, then it will throw an ambiguous error.


 
Types of Action Method.

  • Action Method
  • Non Action Method

How to restrict the public action method in MVC?
To restrict the public action method in MVC, we can use the “NonAction” attribute. The “NonAction” attribute exists in the “System.Web.MVC” namespace.
 
Example of NonAction attribute in ASP.NET MVC.
    [NonAction]  
      public string GetFullName(string strFirstName, string strLastName)  
      {  
              return strFirstName + " " + strLastName;  
      }  

How to call Action Method?
Syntax

YourDomainName/ControllerName/ActionMethodName
 
Example
 
localhost/Home/Index

How to change default Action Method?
The default Action method is configured in the RouteConfig.cs class. By default, the Action Method is the “Index” action method. Change the “Index” action method name as per our requirement.
    public static void RegisterRoutes(RouteCollection routes)  
            {  
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
      
                routes.MapRoute(  
                    name: "Default",  
                    url: "{controller}/{action}/{id}",  
                    defaults: new { controller = "Home", action = "Message", id = UrlParameter.Optional }  
                );  
            }  

You can see in the above code that we have changed the action method name to “Message” instead of “Index” by default.
 
How does the default action get executed?
Default controller and action method are configured in RouteConfig.cs class. By default, Controller is the Home Controller and default Action Method is the “Index” action method.
 
Example of default action method
    public static void RegisterRoutes(RouteCollection routes)  
            {  
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
      
                routes.MapRoute(  
                    name: "Default",  
                    url: "{controller}/{action}/{id}",  
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  
                );  
            }  



ASP.NET MVC Hosting - HostForLIFE.eu :: Session in ASP.NET Core MVC .NET 8

clock December 11, 2024 06:09 by author Peter

What is a Session?
Session is KEY-VALUE structure to store the user specific data. In Asp.Net Core .NET 8 session is not enable by default, we have to enable it. Session data persists across multiple HTTP requests.


How many ways for Session storage?

In-Memory Cache: Server base storage. Storage capacity is depend upon server’s available memory. Best for single server base environment.
Distributed Cache: Session storage not on one server its store on multiple server. Distributed cache work with Redis, Sql Server etc. .

How to Enable Session in .Net 8 Asp.Net Core MVC Application?

builder.Services.AddSession();

Add another line just after app declaration line:
app.UseSession();

How to set or store the value in session?
Create or Setting Session value.

Syntax
HttpContext.Session.SetString(KEY,VALUE);
HttpContext.Session.SetInt22(KEY,VALUE);


Example
HttpContext.Session.SetString(“USERNAME”, UserName);
HttpContext.Session.SetString(“USERID”,Convert.ToString(UserID));

How to get or retrieve the value of session?
Getting Session value.

Syntax
HttpContext.Session.GetString(KEY);

HttpContext.Session.GetInt22(KEY);


Example
HttpContext.Session.GetString(“USERNAME”);

HttpContext.Session.GetString(“USERID”);


How to remove particular session key?
You can easily remove a specific session key.

Syntax
HttpContext.Session.Remove(KEY);

Example
HttpContext.Session.Remove(“UESERNAME”);

How to remove all session keys?
You can delete/remove/clear all sessions in one go.

HttpContext.Session.Clear();


Clear: It remove all the current session entries from the server.

OR

HttpContext.SignOutAsync();

SignOutAsync: It end the current user session and remove or clear the user’s authentication cookie from the server.
Walk-through on session implementation

In this article I had used Visual Studio 2022. After follow step by step you are able to implement SESSION in your Asp.Net Core project.

 

 

Above screenshot is a view of default project structure of Asp.Net Core .NET 8.

Now open program.cs file to add following line:
builder.Services.AddSession(); //

app.UseSession(); //after app declaration.


Update Program.cs file Code:
var builder = WebApplication.CreateBuilder(args);

// Add services to the container
builder.Services.AddControllersWithViews();

// Configure session service for the application
builder.Services.AddSession();

var app = builder.Build();

// Enable the Session Middleware
app.UseSession();

// Configure the HTTP request pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Open the HomeController.cs file from CONTROLLERS folder.

Update HomeController.cs file code:
using LearnCore.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;

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

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

        public IActionResult Index()
        {
            // Create SESSION called USERNAME and store value "Peter Scott"
            HttpContext.Session.SetString("USERNAME", "
Peter Scott");
            return View();
        }

        public IActionResult Privacy()
        {
            // Get value from SESSION
            string UserValName = HttpContext.Session.GetString("USERNAME")?.ToString();
            ViewBag.UserName = UserValName;
            return View();
        }

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

Open the Privacy.cshtml file from VIEWS àHOME.

Update the Privacy.cshtml file code :
@{
    ViewData["Title"] = "Privacy Policy";
}

<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

<h2>
    User Name: <i><u>@ViewBag.UserName</u></i>
</h2>

Now press F5 to run the project. Happy Coding!



ASP.NET MVC Hosting - HostForLIFE.eu :: Application Using Backbone.js with ASP.NET MVC

clock December 3, 2024 07:37 by author Peter

This article shows the use of Backbone.js with ASP.NET MVC with a simple MVC application using backbone.js. Before this article we used backbone with HTML but here we will use with cshtml.



Use the following procedure to create the sample.

Step 1

  • Create a Web API application with the following:
  • Start Visual Studio 2013.
  • From Start window Select "New Project".
  • Select "Installed" -> "Template" -> "Visual C#" -> "Web" -> "Visual Studio 2012" and select "ASP.NET MVC4 Web Application".
  • Click the "OK" button.

From the MVC4 project window select "Empty application".

Click on the "OK" button.

Step 2
Now add a MVC controller class in the Controller folder.

  • In the Solution Explorer.
  • Right-click on the Controller folder.
  • Select "Add" -> "Controller" then select "Empty MVC Controller" and click on the "Add" button.

Add the "Person Action method".
public class HomeController : Controller
{
    //
    // GET: /Home/
    public ActionResult Index()
    {
        return View();
    }
    public ActionResult Person()
    {
        return View();
    }
}


Now we need to add a "index.cshtml" view in the Home folder. Right-click on the "Person()" action method, select "Add view" then open an "Add View" window then click on the "Add" button.

Add the following code in this view:
@{
    ViewBag.Title = "Person";
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Backbone.js Web App</title>
    <link href="~/Content/style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <div id="persons"></div>
    <script id="personTemplate" type="text/template">
        <img src="<%= photo %>" alt="<%= name %>" />
        <h1><%= name %><span><%= type %></span></h1>
        <div><%= address %></div>
        <dl>
            <dt>Tel:</dt>
            <dd><%= tel %></dd>
            <dt>Email:</dt>
            <dd><a href="mailto:<%= email %>"><%= email %></a></dd>
        </dl>
    </script>
    <script src="~/Scripts/jquery-1.8.2.min.js"></script>
    <script src="~/Scripts/json2.js"></script>
    <script src="~/Scripts/underscore-min.js"></script>
    <script src="~/Scripts/backbone-min.js"></script>
    <script src="~/Scripts/main.js" type="text/javascript"></script>
    </div>
</body>
</html>

Step 3
Now we create a JavaScript file as "main.js".

  • In the Solution Explorer.
  • Right-click on the "Scripts" folder select "Add" -> "JavaScript".

Click on the "Add" button.

Add the following code;
(function ($) {
    //demo data
    var persons = [       { name: "Person 1", address: "Address 1", tel: "0123456789", email: "[email protected]", type: "family" },       { name: "Person 2", address: "Address 2", tel: "0123456789", email: "[email protected]", type: "family" },
    ];
    //define product model
    var Person= Backbone.Model.extend({
        defaults: {
            photo: "img/placeholder.png"
    }
    });
//define directory collection
var Directory = Backbone.Collection.extend({
    model: Person
});
//define individual person view
var PersonView = Backbone.View.extend({
    tagName: "article",
    className: "person-container",
    template: $("#personTemplate").html(),
    render: function () {
        var tmpl = _.template(this.template);
        $(this.el).html(tmpl(this.model.toJSON()));
        return  this;
    }
});
//define master view
var DirectoryView = Backbone.View.extend({
    el: $("#persons"),
    initialize: function () {
        this.collection = new Directory(persons);
        this.render();
    },
    render: function () {
        var that = this;
        _.each(this.collection.models, function (item) {
            that.renderPerson(item);
        }, this);
    },
    renderPerson: function (item) {
        var personView = new PersonView({
            model: item
        });
        this.$el.append(personView.render().el);
    }
});
//create instance of master view
var directory = new DirectoryView();
} (jQuery));

There is were we need the other scripting files "backbone.js","underscore.js", "json2.js" and "jquery-1.8.2.min.js".

Step 4
Now execute the application:



About HostForLIFE.eu

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

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


Tag cloud

Sign in