Mid From PDF MVC ASP.NET Core 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

zure 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

Health Checks ASP.NET Core HealthChecks Expose /health endpoints

This gives a complete production-ready workflow from deployment to monitoring.

dvanced & 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:

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

{

Console.WriteLine("Before Middleware 1");

wait next();

Console.WriteLine("After Middleware 1");

});

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

{

Console.WriteLine("Middleware 2");

wait next();

});

pp.Run(async context =>

{

wait 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();

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

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) =>

wait 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}`);

});

wait connection.start();

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

5⃣ Background Services (IHostedService)

  • 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");

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

pp.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");

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

}));

});

pp.UseRateLimiter();

✅ Helps protect APIs from abuse or DoS attacks.

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

pp.UseExceptionHandler(errorApp =>

{

errorApp.Run(async context =>

{
var error =

context.Features.Get<IExceptionHandlerPathFeature>();

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

context.Response.StatusCode = 500;

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

});

});

1⃣1⃣ Anti-Forgery Tokens

  • Protects against CSRF attacks
  • In Razor:

<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

uth

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
  • 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" };

pp.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();

Integrating GraphQL

builder.Services.AddGraphQLServer()

.AddQueryType<Query>();

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

More from ASP.NET Core MVC Tutorial

All questions for this course
Toolliyo Assistant
Ask about tutorials, ebooks, training, pricing, mentor services, and support. I use public site content only—not admin or internal tools.

care@toolliyo.com

Need callback? Share your details