Mid MVC

Alerts – Email/SMS/Slack for failures or slow responses ✅ Helps detect issues before users notice. 🧠 Summary Table Topic Tool / Feature Notes IIS Deployment ASP.NET Core Hosting Bundle IIS acts as reverse proxy Docker Deployment Dockerfile Build + runtime stages Azure App Service PaaS Easy scaling, HTTPS CI/CD GitHub Actions / Azure DevOps Automated build/test/deploy Logging ILogger, Serilog, NLog Use structured logging Monitoring Application Insights, Prometheus Track metrics, uptime Follow : Health Checks ASP.NET Core HealthChecks Expose /health endpoints This gives a complete production-ready workflow from deployment to monitoring. Advanced & Modern Topics Middleware Pipeline in Depth?

ASP.NET Core handles HTTP requests through a middleware pipeline, which is a

sequence of components where each can:

  • Inspect or modify the request
  • Call the next middleware
  • Short-circuit the pipeline

Pipeline Flow:

Request -> Middleware1 -> Middleware2 -> Middleware3 -> Endpoint ->

Response back

Example:

app.Use(async (context, next) =>

Console.WriteLine("Before Middleware 1");

await next();

Console.WriteLine("After Middleware 1");

});

app.Use(async (context, next) =>

Console.WriteLine("Middleware 2");

Follow :

await next();

});

app.Run(async context =>

await context.Response.WriteAsync("Hello World");

});

Key Points:

  • Order matters!
  • Use → can call next middleware
  • Run → terminates pipeline (no next)
  • Map → conditionally routes requests

2⃣ How ASP.NET Core Handles gRPC

  • gRPC uses HTTP/2, binary serialization (Protobuf), and strongly typed contracts.
  • Add gRPC service:

builder.Services.AddGrpc();

app.MapGrpcService<MyGrpcService>();

  • Clients can call server methods over HTTP/2 for high-performance RPC.

Use Cases: Microservices, real-time streaming, low-latency APIs.

3⃣ SignalR vs WebSockets

Follow :

Feature WebSockets SignalR

Protocol Low-level

TCP-based

High-level abstraction

Transpor

Only WebSockets Fallbacks: WebSockets → SSE → Long Polling

Usage Real-time

messages

Real-time hubs with automatic reconnection, grouping,

scaling

✅ Use SignalR for apps needing broadcast, connection management, and fallbacks.

4⃣ Using SignalR for Real-Time Communication

// Hub

public class ChatHub : Hub

public async Task SendMessage(string user, string message) =>

await Clients.All.SendAsync("ReceiveMessage", user,

message);

// Client (JavaScript)

const connection = new signalR.HubConnectionBuilder()

.withUrl("/chathub")

.build();

connection.on("ReceiveMessage", (user, message) => {

console.log(`${user}: ${message}`);

});

await connection.start();

await connection.invoke("SendMessage", "Alice", "Hello!");

5⃣ Background Services (IHostedService)

Follow :

  • For long-running tasks or scheduled jobs
  • Implement IHostedService or extend BackgroundService

public class TimedWorker : BackgroundService

protected override async Task ExecuteAsync(CancellationToken

stoppingToken)

while (!stoppingToken.IsCancellationRequested)

Console.WriteLine("Running background task");

await Task.Delay(10000, stoppingToken);

builder.Services.AddHostedService<TimedWorker>();

✅ Good for periodic jobs, email processing, queue consumers.

6⃣ Hangfire or Quartz.NET for Background Jobs

Hangfire Example:

app.UseHangfireDashboard();

RecurringJob.AddOrUpdate(() => Console.WriteLine("Recurring job"),

Cron.Daily);

Quartz.NET: Supports cron-like scheduling and clustered execution.

7⃣ Health Checking in ASP.NET Core

builder.Services.AddHealthChecks()

.AddSqlServer(connectionString)

.AddCheck<CustomHealthCheck>("CustomCheck");

Follow :

app.MapHealthChecks("/health");

Custom Health Check Example:

public class CustomHealthCheck : IHealthCheck

public Task<HealthCheckResult>

CheckHealthAsync(HealthCheckContext context, CancellationToken

token) =>

Task.FromResult(HealthCheckResult.Healthy("Everything OK"));

8⃣ Rate Limiting Middleware in .NET 8

builder.Services.AddRateLimiter(options =>

options.GlobalLimiter =

PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>

RateLimitPartition.GetFixedWindowLimiter(httpContext.Connection.Remo

teIpAddress?.ToString()!, _ =>

new FixedWindowRateLimiterOptions

PermitLimit = 10,

Window = TimeSpan.FromMinutes(1),

QueueLimit = 2

}));

});

app.UseRateLimiter();

✅ Helps protect APIs from abuse or DoS attacks.

Follow :

9⃣ DataAnnotations for Validation

public class Product

[Required]

public string Name { get; set; }

[Range(1, 100)]

public decimal Price { get; set; }

  • Works with model binding
  • Automatic client & server-side validation with Razor or API endpoints

🔟 Global Exception Logging

app.UseExceptionHandler(errorApp =>

errorApp.Run(async context =>

var error =

context.Features.Get<IExceptionHandlerPathFeature>();

Log.Error(error.Error, "Unhandled exception");

context.Response.StatusCode = 500;

await context.Response.WriteAsync("An error occurred");

});

});

1⃣1⃣ Anti-Forgery Tokens

  • Protects against CSRF attacks
  • In Razor:

Follow :

<form method="post">

@Html.AntiForgeryToken()

</form>

  • In API: use services.AddAntiforgery(), validate via

[ValidateAntiForgeryToken].

1⃣2⃣ Middleware vs Filters vs Handlers

Concept When It Runs Scope Example

Middleware Before/after request Global Logging, authentication

Filters Around controller/action Controller/action Authorization, validation

Handlers Authentication/Authorization Global or

endpoint

JWT handler, Cookie

auth

1⃣3⃣ DI vs Service Locator

  • Dependency Injection: Dependencies are injected via constructor or method.

Promotes loose coupling.

  • Service Locator: Class fetches dependencies from a central registry. Leads to

hidden dependencies, harder to test.

✅ DI is the preferred modern pattern.

Performance Tuning Best Practices

  • Use async/await for I/O bound tasks
  • Use response caching & output caching

Follow :

  • Minimize middleware overhead
  • Use compiled queries for EF Core
  • Enable gzip compression
  • Use object pooling for high-load scenarios

Localization & Globalization

builder.Services.AddLocalization(options => options.ResourcesPath =

"Resources");

var supportedCultures = new[] { "en-US", "fr-FR" };

app.UseRequestLocalization(new RequestLocalizationOptions

DefaultRequestCulture = new RequestCulture("en-US"),

SupportedCultures = supportedCultures,

SupportedUICultures = supportedCultures

});

✅ Allows apps to support multiple languages & regions.

Output & Input Formatters

  • Input Formatters: Deserialize request body (JSON, XML, Protobuf)
  • Output Formatters: Serialize response

builder.Services.AddControllers()

.AddJsonOptions(opt =>

opt.JsonSerializerOptions.PropertyNamingPolicy = null)

.AddXmlSerializerFormatters();

Follow :

Integrating GraphQL

builder.Services.AddGraphQLServer()

.AddQueryType<Query>();

app.MapGraphQL();

  • Query APIs flexibly, single endpoint
  • Better for nested object queries vs REST

Common Pitfalls Migrating from MVC 5 to ASP.NET

Core MVC

  • Global.asax → Program.cs & Startup.cs
  • Web.config → appsettings.json
  • HttpContext.Items, Session handling differs
  • Filter pipeline changed
  • Dependency injection built-in (no manual factories)
  • Authentication/Authorization model changed (Claims-based by default)
  • No System.Web; libraries must be compatible

Follow :

More from ASP.NET Core MVC Tutorial

All questions for this course