Meet The Author

I'm Ethan Jackson, An 25 years old blogger Currently living in London, United Kingdom. I'm a Skilled Blogger, Part Time web Developer And Creating new things as a web Designer.

author

How to Create Custom Middleware in ASP.NET Core?

Leave a Comment

Middleware: What is it?
A middleware is a little piece of software that handles HTTP requests and responses in ASP.NET Core.
Every middleware operates in a pipeline and is capable of:

  • Execute a task prior to the subsequent middleware execution.
  • After it runs, take a certain action, or
  • even prevent the request from being processed further.

To put it simply, middleware can examine, alter, or end a request or response, much like a checkpoint in the request pipeline.

Default Middleware Examples

ASP.NET Core comes with built-in middleware such as:

  • UseRouting() — Handles URL routing

  • UseAuthentication() — Handles login/auth

  • UseAuthorization() — Manages access control

  • UseStaticFiles() — Serves static files like images or CSS

You can also create your own custom middleware to add specific logic (like logging, validation, or tracking).

Step-by-Step: Creating Custom Middleware

Let’s create a simple custom middleware that logs each incoming request and outgoing response.

Step 1. Create the Middleware Class
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using System;

public class MyCustomMiddleware
{
    private readonly RequestDelegate _next;

    // Constructor to accept the next middleware in the pipeline
    public MyCustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // Main method to handle request and response
    public async Task InvokeAsync(HttpContext context)
    {
        // Code before the next middleware runs
        Console.WriteLine($" Request received: {context.Request.Method} {context.Request.Path}");

        // Call the next middleware in the pipeline
        await _next(context);

        // Code after the next middleware runs
        Console.WriteLine($" Response sent: {context.Response.StatusCode}");
    }
}
Step 2. Create an Extension Method (for cleaner code)

It’s good practice to add an extension method so you can easily use your middleware.

using Microsoft.AspNetCore.Builder;

public static class MyCustomMiddlewareExtensions
{
    public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyCustomMiddleware>();
    }
}
Step 3. Register the Middleware in Program.cs

In .NET 6+, middleware is added in the request pipeline using the app object.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Custom middleware registration
app.UseMyCustomMiddleware();

// Example controller routing
app.MapControllers();

app.Run();

Step 4. Run and Test

Now run your application (Ctrl + F5).

When you send a request (like GET /api/values), you’ll see logs in the console:

Request received: GET /api/values
Response sent: 200

Your custom middleware successfully intercepted and logged the request and response!

How Middleware Works Internally?

When a request comes in:

  1. The first middleware receives it.

  2. It can do something (like logging) and call the next middleware.

  3. The request flows through all middleware components.

  4. The response flows back through them in reverse order.

Visual Flow Diagram
Request → [Middleware 1] → [Middleware 2] → [Middleware 3] → Endpoint
             ↑                                      ↓
          Response ← [Middleware 3] ← [Middleware 2] ← [Middleware 1]
When to Use Custom Middleware

Custom middleware is useful for:

  • Logging requests and responses

  • Handling exceptions globally

  • Adding custom headers or tokens

  • Measuring performance

  • Implementing request filters (e.g., IP blocking)

Example: Adding a Header Middleware

Here’s another short example that adds a custom header to all responses:

public class HeaderMiddleware
{
    private readonly RequestDelegate _next;

    public HeaderMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        await _next(context);
        context.Response.Headers.Add("X-Powered-By", "SandhiyaCustomMiddleware");
    }
}

Register it in Program.cs:

app.UseMiddleware<HeaderMiddleware>();

Every response from your app will now include:

X-Powered-By: SandhiyaCustomMiddleware

Summary

StepAction
1Create a middleware class with InvokeAsync(HttpContext)
2Add an extension method for better reusability
3Register it in the request pipeline using the app.UseMyCustomMiddleware()
4Test by sending a request and checking the console or response headers

Conclusion

Custom middleware gives you complete control over the request and response pipeline in ASP.NET Core.

It helps you write clean, reusable, and centralized logic for logging, authentication, or any pre/post-processing.

In short: Middleware is the heart of ASP.NET Core request handling — and custom middleware lets you extend that heart for your unique business needs.

Windows Hosting Recommendation

HostForLIFE.eu receives Spotlight standing advantage award for providing recommended, cheap and fast ecommerce Hosting including the latest Magento. From the leading technology company, Microsoft. All the servers are equipped with the newest Windows Server 2022 R2, SQL Server 2022, ASP.NET Core 10.0 , ASP.NET MVC, Silverlight 5, WebMatrix and Visual Studio Lightswitch. Security and performance are at the core of their Magento hosting operations to confirm every website and/or application hosted on their servers is highly secured and performs at optimum level. mutually of the European ASP.NET hosting suppliers, HostForLIFE guarantees 99.9% uptime and fast loading speed. From €3.49/month , HostForLIFE provides you with unlimited disk space, unlimited domains, unlimited bandwidth,etc, for your website hosting needs.
 
https://hostforlifeasp.net/
Read More

Jenkins CI/CD for ASP.NET Core + Angular App Deployment

Leave a Comment

Applications built using Angular for the frontend and ASP.NET Core for the backend are frequently deployed by hand, requiring file copies, Visual Studio publishing, IIS restarts, and other steps. Manual deployment becomes dangerous as your team increases, although it works well for small projects. One minor error could overwrite settings or result in downtime.

Jenkins' Continuous Integration and Continuous Deployment (CI/CD) technology can help with it.
Every time you push code, it swiftly and safely builds, tests, and deploys your project. I'll walk you through the process of utilizing the Jenkins pipeline to deploy a full-stack application (Angular + ASP.NET Core) on a Windows server (IIS) in this post.

Requirements

Before we start, make sure you have:

  • Installed Jenkins (Windows or Linux)

  • Installed .NET SDK (e.g. .NET 8.0) on the Jenkins server

  • Installed Node.js and Angular CLI

  • Installed Git (for source code checkout)

  • Access to your IIS server for deployment

Project Structure

Below is a common folder structure we’ll work with:

HFLDemoApp/
 ├── WebAPI/             # ASP.NET Core Backend
 ├── ClientApp/          # Angular Frontend
 ├── Jenkinsfile         # Jenkins pipeline script
 ├── deploy.ps1          # PowerShell script for IIS deployment

Step 1. Create a Jenkins Pipeline Job

  1. Open Jenkins Dashboard → New Item → Pipeline

  2. Give it a name, e.g., RajeshDemoApp-CI-CD

  3. Under Pipeline definition, select Pipeline script from SCM

  4. Choose Git, and provide your repo URL.

  5. Jenkins will now read the Jenkinsfile from your repository.

Step 2. Jenkinsfile Configuration

Here’s a simple Jenkinsfile example for our project:

pipeline {
    agent any

    stages {
        stage('Checkout Code') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo'
            }
        }

        stage('Build Angular') {
            steps {
                dir('ClientApp') {
                    bat 'npm install'
                    bat 'ng build --configuration production'
                }
            }
        }

        stage('Build .NET Core') {
            steps {
                dir('WebAPI') {
                    bat 'dotnet restore'
                    bat 'dotnet publish -c Release -r win-x64 -o ../publish'
                }
            }
        }

        stage('Deploy to IIS') {
            steps {
                bat 'powershell .\\deploy.ps1'
            }
        }
    }
}

Note:
If you’re using Linux agents, replace bat with sh.

Step 3. Create PowerShell Script for Deployment

Let’s create a PowerShell file named deploy.ps1 at the root of your repo.

This script will:

  • Stop IIS site

  • Backup old files

  • Copy new build files

  • Restart IIS site

Write-Host "Starting deployment..."

$source = "C:\Jenkins\workspace\MyApp-CI-CD\publish"
$destination = "C:\inetpub\wwwroot\RajeshDemoApp"
$backup = "C:\Backup\MyApp_" + (Get-Date -Format "yyyyMMdd_HHmmss")

# Stop IIS
iisreset /stop

# Backup existing site
if (Test-Path $destination) {
    Copy-Item $destination $backup -Recurse
    Write-Host "Backup created at $backup"
}

# Copy new files
Copy-Item $source\* $destination -Recurse -Force

# Start IIS
iisreset /start

Write-Host "Deployment completed successfully."

Step 4. Handle Configuration Files

We usually have environment-specific files like:

  • appsettings.Production.json

  • environment.prod.ts

You can use a small PowerShell snippet to replace these files based on environment before publishing.

Example:

Copy-Item ".\Configs\Production\appsettings.json" ".\WebAPI\appsettings.json" -Force

Step 5. Run the Pipeline

  1. Commit and push your code (including Jenkinsfile).

  2. Go to Jenkins → click Build Now.

  3. Jenkins will run each stage — build Angular, build .NET, deploy to IIS.

Step 6. Troubleshooting Tips

If deployment fails:

  • Check Jenkins console logs (very helpful).

  • Make sure IIS user has write permission to your deployment folder.

  • Ensure Node.js, Angular CLI, and .NET SDK paths are configured in Jenkins.

Step 7. Benefits of Using CI/CD

After setting this up once, your deployments become:

  • Automatic – no manual file copying

  • Consistent – same steps every time

  • Fast – 1-click deployment from Jenkins

  • Safe – automatic backup and rollback

Conclusion

By combining Jenkins, ASP.NET Core, and Angular, we can automate our entire deployment process.

No more “it works on my machine” issues — your build, test, and deployment happen exactly the same way every time.

Windows Hosting Recommendation

HostForLIFE receives Spotlight standing advantage award for providing recommended, cheap and fast ecommerce Hosting including the latest Magento. From the leading technology company, Microsoft. All the servers are equipped with the newest Windows Server 2022 R2, SQL Server 2022, ASP.NET Core 10.0 , ASP.NET MVC, Silverlight 5, WebMatrix and Visual Studio Lightswitch. Security and performance are at the core of their Magento hosting operations to confirm every website and/or application hosted on their servers is highly secured and performs at optimum level. mutually of the European ASP.NET hosting suppliers, HostForLIFE guarantees 99.9% uptime and fast loading speed. From €3.49/month , HostForLIFE provides you with unlimited disk space, unlimited domains, unlimited bandwidth,etc, for your website hosting needs.
 
https://hostforlifeasp.net/
Read More

Managing ASP.NET Session Problems in Several Tabs of the Browser: Making Sure Popups Have Correct User Data

Leave a Comment

It can be challenging to manage user sessions across several browser tabs in contemporary web applications, particularly when you wish to display dynamic user data via pop-ups like an application form. This blog post will examine a typical ASP.NET session problem and offer a thorough, step-by-step fix.

The Scenario
Imagine this situation:

  • Tab 1: User A logs in.
  • Tab 2: User B logs in in the same browser.
  • You return to Tab 1 and try to apply IPO.

Problem
The pop-up shows User A’s name (from page load).
Backend, however, processes User B’s session data (because the session is shared across tabs).

This mismatch can confuse users and cause data integrity issues.

Why This Happens

ASP.NET sessions are per browser, not per tab.
Tab 1: logs in as User A → Session["ClientFname"] = "A".
Tab 2: logs in as User B → Session["ClientFname"] = "B".
Both tabs now share the same session cookie.

Result: Frontend shows old cached data (User A), while the backend processes the latest session (User B).

Goal

We want to ensure that:

  • The frontend popup always shows the correct client details.
  • The backend request corresponds to the same user shown in the pop-up.
  • Solution: Fetch Data Dynamically from Backend

The most reliable approach is to fetch user session data dynamically from the server when the pop-up is triggered. This ensures the displayed data always matches the backend session.

Step 1. Add a WebMethod in ASP.NET

In your ASPX code-behind, create a WebMethod to return session data:

[System.Web.Services.WebMethod]
public static object GetClientSessionData()
{
    try
    {
        string name = HttpContext.Current.Session["ClientFname"]?.ToString() ?? "";
        string pan = HttpContext.Current.Session["Pan"]?.ToString() ?? "";
        string dp = HttpContext.Current.Session["Depository"]?.ToString() ?? "";

        return new
        {
            ClientFname = name,
            Pan = pan,
            Depository = dp
        };
    }
    catch (Exception ex)
    {
        return new { Error = ex.Message };
    }
}

Tip: You can also create a strong-typed class for clarity instead of returning an anonymous object.



Step 2. Call the WebMethod from JavaScript

When the user clicks Apply IPO, call the WebMethod to get the current session data:

When the user clicks Apply IPO, call the WebMethod to get the current session data:

function submitalldata() {
    // Get UPI ID entered by user
    var UPIID = document.getElementById("<%=txtupiid.ClientID%>").value;

    // Call backend WebMethod to get session data
    $.ajax({
        type: "POST",
        url: "ApplyIPO.aspx/GetClientSessionData",
        data: '{}',  // no parameters needed
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            var data = response.d;

            if (data.Error) {
                alert("Error: " + data.Error);
                return;
            }

            // Populate popup fields with session data
            document.getElementById("clname").innerText = data.ClientFname;
            document.getElementById("clpan").innerText = data.Pan;
            document.getElementById("cldpid").innerText = data.Depository;
            document.getElementById("clupi").innerText = UPIID;
            document.getElementById("clupiname").innerText = data.ClientFname; // optional if needed

            // Show popup modal dynamically
            $('#conformModalpopup').modal('show');
        },
        error: function (xhr, status, error) {
            console.error("Error fetching session data:", error);
        }
    });

    // Prevent full postback
    return false;
}
Step 3. What Happens Now

The popup always fetches current session data from the backend.

Even with multiple tabs open, the correct user details are shown.

You avoid mismatches between frontend and backend.

ASPX Markup (Frontend)

<!-- Apply Button -->

<div class="modal-footer">

<a id="applybtn" runat="server" onclick="return submitalldata();">APPLY</a>

</div>

<!-- Popup Modal -->

<div class="modal fade" id="conformModalpopup" role="dialog" aria-labelledby="exampleModalCenterTitle">

<div class="modal-dialog modal-dialog-centered" role="document">

<div class="modal-content newboarderradius modalfooterclass">

<div class="modal-header popupheader">

<h5 class="modal-title"><b>Client Details Verification</b></h5>

<button type="button" class="close clientpopupclose btn-close" data-bs-dismiss="modal" aria-label="Close">

<span>&times;</span>

</button>

</div>

<div class="modal-body">

<div class="verification">

<table class="usertblvalidation">

<tr>

<td class="useralignment">Client Name</td>

<td>:</td>

<td id="clname" runat="server" class="useralignment"></td>

</tr>

<tr>

<td class="useralignment">Pan No</td>

<td>:</td>

<td id="clpan" runat="server" class="useralignment"></td>

</tr>

<tr>

<td class="useralignment">DP ID</td>

<td>:</td>

<td id="cldpid" runat="server" class="useralignment"></td>

</tr>

<tr>

<td class="useralignment">UPI ID</td>

<td>:</td>

<td id="clupi" class="useralignment"></td>

</tr>

<tr>

<td class="useralignment">UPI ID Name</td>

<td>:</td>

<td id="clupiname" class="useralignment"></td>

</tr>

</table>

</div>

</div>

<div class="modal-footer verifiedfooter">

<div class="footerbtnopenclose">

<button type="button" class="btn btn-white verificationpopup" data-bs-dismiss="modal" id="cancelbtn">Cancel</button>

<button type="button" class="btn btn-white modify-popup verificationpopup" id="confirm_txt" onclick="message();">Confirm</button>

</div>

<div class="input-container upidivcontent">

<label id="conform_txtbx"></label>

</div>

</div>

</div>

</div>

</div>

How It Works?

You click “APPLY”.

submitalldata() runs → calls backend method GetClientSessionData().

The server sends back the current session user info (ClientFname, PAN, etc.).

JavaScript fills your modal table dynamically.

Bootstrap modal (#conformModalpopup) opens showing correct data.

No full postback — everything happens via AJAX. 

Windows Hosting Recommendation

HostForLIFE.eu receives Spotlight standing advantage award for providing recommended, cheap and fast ecommerce Hosting including the latest Magento. From the leading technology company, Microsoft. All the servers are equipped with the newest Windows Server 2022 R2, SQL Server 2022, ASP.NET Core 10.0 , ASP.NET MVC, Silverlight 5, WebMatrix and Visual Studio Lightswitch. Security and performance are at the core of their Magento hosting operations to confirm every website and/or application hosted on their servers is highly secured and performs at optimum level. mutually of the European ASP.NET hosting suppliers, HostForLIFE guarantees 99.9% uptime and fast loading speed. From €3.49/month , HostForLIFE provides you with unlimited disk space, unlimited domains, unlimited bandwidth,etc, for your website hosting needs.
 
https://hostforlifeasp.net/
Read More

Improving nopCommerce Efficiency: Useful Optimization Strategies for Fast Stores

Leave a Comment

Any eCommerce platform must have strong performance, particularly in terms of conversion rates, SEO rankings, and customer experience. Although nopCommerce 4.80.9, which is based on the robust ASP.NET Core framework, has a strong performance foundation by default, real-world stores frequently need tweaking to get blazingly fast page loads.



This post will discuss doable nopCommerce speed optimization strategies that you can put into practice immediately, ranging from frontend and server-level improvements to database tuning and caching.

1. Enable and Optimize Caching

nopCommerce uses a built-in caching mechanism to store frequently accessed data (such as settings, categories, products, and plugins).
However, the cache configuration can significantly impact performance.

What to Do

Ensure caching is enabled in appsettings.json

"DistributedCacheConfig": {
  "Enabled": true,
  "UseRedis": true,
  "RedisConnectionString": "localhost:6379"
}
  • Use Redis cache instead of in-memory cache when you’re running multiple instances (e.g., on Azure or AWS load balancing).

  • Avoid unnecessary cache invalidation. When writing plugins or custom logic, be careful not to clear global cache ( _cache.RemoveByPattern("*") ) unless absolutely required.

Pro Tip

Use ICacheKeyService to manage cache keys and dependency tags efficiently.

2. Optimize Database Performance

Database queries are often the bottleneck in nopCommerce applications.
Start by reviewing long-running SQL queries using tools like SQL Server Profiler or New Relic .

Optimization Techniques

  1. Add proper indexes to frequently used columns in tables like:

    • Product

    • Product_Category_Mapping

    • Order

    • Customer

    Example

    CREATE INDEX IX_Product_Published_Deleted ON Product (Published, Deleted)
  1. Avoid N+1 queries in custom LINQ or repository code.
    Use .Include() wisely when fetching related data.

  2. Use Stored Procedures for batch updates or heavy reporting.

  3. Enable Query Caching when using custom queries.

3. Minimize Plugin Overhead

nopCommerce’s plugin system is powerful — but too many plugins can increase startup time and memory consumption.

What to Do

  • Remove unused plugins from /Plugins folder.

  • Disable unnecessary plugins in Admin → Configuration → Local Plugins.

  • Avoid duplicate functionality.

  • When developing your own plugin, use async/await for all I/O operations and dispose of the DbContext properly.

4. Optimize Frontend (CSS, JS, and Images)

Frontend optimization often yields the most visible speed improvement.

Techniques

  1. Enable bundling and minification
    In Admin → Configuration → Settings → General Settings , ensure “Enable bundling and minification” is checked.

  2. Use modern image formats like WebP.

  3. Defer non-critical JavaScript and load analytics asynchronously.

  4. Leverage Cloudflare or CDN to serve static assets globally.

Example of async analytics loading

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>

5. Tune Application Settings

Some configuration tweaks can dramatically reduce load time.

Recommendations

  • Set "UseResponseCompression": true in appsettings.json .

  • Use Kestrel instead of IIS in Linux-based deployments for better throughput.

  • Enable HTTP/2 support.

  • Configure Entity Framework connection pooling for efficient DB access.

Example snippet

builder.Services.AddDbContextPool<NopDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("NopConnection")));

6. Use CDN and Caching Headers

To optimize delivery of static resources:

  • Configure Cache-Control headers for static content.

  • Integrate CDN (Cloudflare, Azure CDN, AWS CloudFront) for global delivery.

Example

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=604800");
    }
});

7. Monitor and Measure

Use monitoring tools like:

  • New Relic or Application Insights for request tracking

  • MiniProfiler for local performance testing

  • SQL Server Profiler for database-level insights

Track slow pages, SQL queries, and memory usage — then optimize based on data, not guesswork.

8. Advanced: Background Task Tuning

nopCommerce runs background tasks like sending emails or syncing feeds.

Tip

  • Reduce frequency of non-critical background tasks.

  • Offload heavy operations to a separate worker service or queue system (e.g., Azure Queue or RabbitMQ).

Example

public class ProductFeedTask : IScheduleTask
{
    public Task ExecuteAsync()
    {
        // Move heavy work to background worker
        return Task.Run(() => _feedService.GenerateAsync());
    }
}

Read More

Entity Framework Tutorial: Set Up the Master Redux Toolkit in Just a Few Minutes!

Leave a Comment

If you've ever felt Redux setup was too verbose or complex, you're not alone. That's exactly why I created a concise, beginner-friendly guide to streamline your Redux Toolkit integration in React projects.

Steps for RTK setup
StepDescription
InstallInstall @reduxjs/toolkit and react-redux
SliceCreate a todoSlice for the todos logic
StoreConfigure the Redux store with the todo reducer
ProviderWrap the app with the Provider
ComponentsUse useSelector and useDispatch in components

1. Install Redux Toolkit & React-Redux

npm install @reduxjs/toolkit react-redux

2. Create the Todo Slice

Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to define how the state can be updated. Once a slice is created, we can export the generated Redux action creators and the reducer function for the whole slice.

// src/redux/todoSlice.js
import { createSlice } from "@reduxjs/toolkit";

const todoSlice = createSlice({
  name: "todo",
  initialState: [],
  reducers: {
    addTodo: (state, action) => {
      state.push({
        id: Date.now(),
        text: action.payload,
        completed: false,
      });
    },
    updateTodo: (state, action) => {
      const { id, newText } = action.payload;
      const todo = state.find((todo) => todo.id === id);
      if (todo) {
        todo.text = newText;
      }
    },
    deleteTodo: (state, action) => {
      return state.filter((t) => t.id !== action.payload);
    },
  },
});
// Export actions and reducer
export const { addTodo, updateTodo, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;

3. Configure the Store

// src/redux/store.js
import { configureStore } from "@reduxjs/toolkit";
import todoReducer from "./todoSlice";

export const store = configureStore({
  reducer: {
    todo: todoReducer,
  },
});

4. Provide the Store to React

// src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { store } from "./redux/store";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

RTK configuration is done, now you can use it in your features/components.

5. TodoInput Component

// src/components/TodoInput.js
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { addTodo } from "../redux/todoSlice";

function TodoInput() {
  const [text, setText] = useState("");
  const dispatch = useDispatch();

  const handleAdd = () => {
    if (text.trim()) {
      dispatch(addTodo(text));
      setText("");
    }
  };

  return (
    <div>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
        placeholder="Enter todo"
      />
      <button onClick={handleAdd}>Add Todo</button>
    </div>
  );
}

export default TodoInput;

6. TodoList Component

// src/components/TodoList.js
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { updateTodo, deleteTodo } from "../redux/todoSlice";

function TodoList() {
  const todos = useSelector(state => state.todo);
  const dispatch = useDispatch();

  const handleUpdate = (id) => {
    const newText = prompt("Update todo text:");
    if (newText) {
      dispatch(updateTodo({ id, newText }));
    }
  };

  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>
          {todo.text}
          <button onClick={() => handleUpdate(todo.id)}>Update</button>
          <button onClick={() => dispatch(deleteTodo(todo.id))}>Delete</button>
        </li>
      ))}
    </ul>
  );
}

export default TodoList;
7. App Component
// src/App.js
import React from "react";
import TodoInput from "./components/TodoInput";
import TodoList from "./components/TodoList";

function App() {
  return (
    <div>
      <h2>Redux Toolkit Todo App</h2>
      <TodoInput />
      <TodoList />
    </div>
  );
}

export default App;

Windows Hosting Recommendation

HostForLIFEASP.NET receives Spotlight standing advantage award for providing recommended, cheap and fast ecommerce Hosting including the latest Magento. From the leading technology company, Microsoft. All the servers are equipped with the newest Windows Server 2022, SQL Server 2019, ASP.NET Core 10.0, ASP.NET MVC 6.0, Silverlight 5, WebMatrix and Visual Studio Lightswitch. Security and performance are at the core of their Magento hosting operations to confirm every website and/or application hosted on their servers is highly secured and performs at optimum level. mutually of the European ASP.NET hosting suppliers, HostForLIFE guarantees 99.9% uptime and fast loading speed. From €3.49/month , HostForLIFE provides you with unlimited disk space, unlimited domains, unlimited bandwidth,etc, for your website hosting needs.
 
https://hostforlifeasp.net/
Read More

ScriptManager, Alert, Alertify, and Confirmation in ASP.NET + JavaScript

Leave a Comment

When you’re building ASP.NET WebForms applications, showing feedback messages to users is crucial. You may use:

  • JavaScript’s built-in dialogs (alert, confirm)

  • Third-party libraries (like alertify.js)

  • ASP.NET’s ScriptManager.RegisterStartupScript to trigger these scripts after server-side operations.

Let’s break this down step by step.

1. ScriptManager.RegisterStartupScript – The Bridge

if (SqlHelper.ExecuteNonQuery(sqlcon, CommandType.Text, sqlBidD, param3) > 0)
{
    ScriptManager.RegisterStartupScript(this, this.GetType(), "success", "order();", true);
}
else
{

    string script = "alertify.alert('" + password Expired + "');";
    ScriptManager.RegisterStartupScript(this, this.GetType(), "alertifyScript", script, true);
}

Explanation

  • SqlHelper.ExecuteNonQuery(...) → Executes a SQL query (insert/update/delete).

  • If success (> 0 rows affected), we call a JavaScript function order();.

  • If failure, we show an alertify alert with error message.

  • ScriptManager.RegisterStartupScript(...) ensures that JavaScript executes after page refresh/postback.

Without ScriptManagerYour JavaScript may not run after a postback in an UpdatePanel.

2. order() function with Alertify

function order() {
    alertify.alert(
        "Application placed successfully.  Please approve it to confirm your application.",
        function (e) {
            if (e) {
                window.history.pushState(null, "", window.location.href);
                window.location = '/orders.aspx';
            } else {
                window.location = '/ClientPages.aspx';
            }
        }
    );
}

Key points

  • alertify.alert(message, callback) → shows a custom styled alert box.

  • The callback function checks e:

    • If user clicks OK → Redirect to /orders.aspx.

    • Else → Redirect to /ClientPages.aspx.

alertify looks modern and customizable compared to plain alert.

3. Example. Normal JavaScript Alert via ScriptManager

if (SqlHelper.ExecuteNonQuery(SqlCon, CommandType.Text, sqlins) > 0)
{
    ScriptManager.RegisterStartupScript(this, this.GetType(), "success", "alert('Client details added in Master.');", true);
}
  • Shows a simple alert("Clientdetails added in Master.").

  • Good for basic messages, but blocking & ugly UI.

4. Redirect with Alert

ScriptManager.RegisterStartupScript(
    this.Page,
    this.Page.GetType(),
    "Msge",
    "alert('Client Details updated successfully');window.location='/Admin/ClientPages.aspx';",
    true
);

Here

  • First shows alert("Client Details updated successfully").

  • Then redirects to /Admin/ClientPages.aspx.

5. Error Handling with Alert

ScriptManager.RegisterStartupScript(
    this.Page,
    typeof(string),
    "alert",
    "alert('" + ex.Message.ToString() + "');",
    true
);
  • Displays server-side error message inside a JavaScript alert.

6. Custom JS Function via ScriptManager

function HideTable() {
    if (detectmob()) {
        document.getElementById("ipotable").style.display="none";
        document.getElementById("tblNodata").style.display="none";
    }
}
ScriptManager.RegisterStartupScript(this.Page, typeof(string), "hide", "HideTable();", true);
  • Calls custom JS function after server-side event.

  • Example: Hide tables if user is on mobile.

7. Thank You Message + Redirect

ScriptManager.RegisterStartupScript(
    this,
    typeof(string),
    "Message",
    "alert('Thank you for providing details. Our Representative will contact you soon.');window.location='/'",
    true
);

Shows message and redirects to homepage /.

8. Plain JavaScript Alert (Client-side)

function Validatecatelog() {
    if ($(".totalclass").text() == "0") {
        alert("Please select API");
        return false;
    }
}
<asp:Button ID="btn_showprice" runat="server" Text="Next" CssClass="price_btn" OnClientClick="return Validatecatelog();"  />
if (dstotal.Tables[0].Rows.Count > 0)
            {
                totaldata = "<span class='totalclass'>" + dstotal.Tables[0].Rows[0]["total"].ToString() + "</span>";
            }
  • Uses alert() directly in JS validation.

  • Blocks execution until user clicks OK.

9. Confirmation Box

let text = "It seems your account is not associated with the provided UPI ID.\n Are you sure you want to proceed?";
if (confirm(text)) {
    document.getElementById("clupiname").innerText = cname1;
    offline_2lcondition();
    return true;
} else {
    return false;
}
  • confirm(message) → Yes/No dialog.

  • Returns true if OK clicked, false if Cancel clicked.

  • Useful for critical actions (delete, update, proceed checks).

Difference: Alert vs Alertify vs Confirm

Featurealert()alertify.alert()confirm()
TypeBuilt-in JSExternal JS LibraryBuilt-in JS
UIOld, blockingModern, customizableOld, blocking
CustomizationNoYes (themes, buttons)No
Callback NoYes (with function)Returns boolean
Redirect SupportOnly with extra JSEasy (inside callback)Easy (via true/false)
Use CaseQuick infoUser-friendly notificationsUser decisions (Yes/No)

Conclusion

  • Use alert() for basic notifications (fast but outdated UI).

  • Use alertify.alert() for modern, user-friendly alerts with callbacks.

  • Use confirm() when you need a Yes/No choice.

  • Always wrap your script inside ScriptManager.RegisterStartupScript in ASP.NET to make sure it works after postbacks.

Read More
Previous PostOlder Posts Home