Welcome to Module 11 of our ASP.NET Core Complete Course: Beginner to Advanced Guide for Modern Web Development. In this module, we dive deep into Security, Logging, and Error Handling, critical components for building secure, reliable, and maintainable ASP.NET Core applications. This comprehensive, SEO-friendly guide covers Handling Exceptions & Custom Error Pages, Logging with ILogger & Serilog, Securing Against CSRF, XSS, SQL Injection, and HTTPS Enforcement & Data Protection.
Packed with practical examples, detailed explanations, real-world scenarios, pros and cons, alternatives, and best practices for security, performance, and error handling, this blog post will equip you with the skills to protect and monitor your applications effectively. Whether you're a beginner or an advanced developer, this module will help you master these essential topics. Let’s get started!
Table of Contents
Introduction to Security, Logging, and Error Handling
Handling Exceptions & Custom Error Pages
What is Exception Handling?
Pros, Cons, and Alternatives
Example: Implementing Exception Handling
Logging with ILogger & Serilog
What is Logging?
Pros, Cons, and Alternatives
Example: Implementing Logging
Securing Against CSRF, XSS, SQL Injection
Understanding Common Security Threats
Pros, Cons, and Alternatives
Example: Implementing Security Measures
HTTPS Enforcement & Data Protection
What are HTTPS and Data Protection?
Pros, Cons, and Alternatives
Example: Implementing HTTPS and Data Protection
Best Practices for Security, Logging, and Error Handling
Security Best Practices
Performance Best Practices
Error Handling Best Practices
Real-Life Example: Building a Secure E-Commerce Platform
Conclusion
FAQs
Introduction to Security, Logging, and Error Handling
Security, logging, and error handling are foundational to building robust ASP.NET Core applications. Security protects applications from threats like CSRF, XSS, and SQL injection. Logging provides insights into application behavior and errors. Error Handling ensures graceful recovery from failures, enhancing user experience.
In Module 11, we’ll explore:
Handling Exceptions & Custom Error Pages: Managing errors gracefully.
Logging with ILogger & Serilog: Capturing application events and errors.
Securing Against CSRF, XSS, SQL Injection: Protecting against common vulnerabilities.
HTTPS Enforcement & Data Protection: Ensuring secure communication and data storage.
This blog post includes detailed explanations, practical examples, pros and cons, alternatives, and best practices for security, performance, and error handling. We’ll also build a real-life e-commerce platform to demonstrate these concepts in action.
Why is this important?
Security: Protects user data and prevents attacks.
Logging: Enables debugging, monitoring, and auditing.
Error Handling: Improves reliability and user experience.
Performance: Optimizes resource usage during logging and error handling.
Compliance: Meets standards like GDPR for data protection.
Let’s dive into each topic with detailed explanations and real-world examples.
Handling Exceptions & Custom Error Pages
What is Exception Handling?
Exception Handling in ASP.NET Core involves catching and processing errors to prevent application crashes and provide user-friendly error messages. Custom Error Pages enhance the user experience by displaying tailored error pages for different HTTP status codes (e.g., 404, 500).
Key Features
Exception Filters: Handle errors in MVC controllers.
Middleware: Use UseExceptionHandler for global error handling.
Custom Pages: Display user-friendly error pages.
Status Codes: Map exceptions to appropriate HTTP status codes.
Pros, Cons, and Alternatives for Exception Handling
Pros
Reliability: Prevents application crashes by catching errors.
User Experience: Displays friendly error messages.
Flexibility: Supports global, controller, or action-level error handling.
Built-in: ASP.NET Core provides robust exception handling APIs.
Cons
Complexity: Overuse of try-catch can clutter code.
Performance: Excessive error handling can impact performance.
Debugging: Overly generic handling may obscure root causes.
Alternatives
Global Exception Filters: For MVC-specific error handling.
Middleware: For pipeline-level error handling.
Third-Party Libraries: Use libraries like Elmah for advanced error logging.
Application Insights: For cloud-based error tracking.
Example: Implementing Exception Handling
Let’s create an application with global exception handling and custom error pages.
Step 1: Create a New MVC Project
dotnet new mvc -o SecureApp
cd SecureApp
Step 2: Configure Exception HandlingUpdate Program.cs:
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Step 3: Create Custom Error PagesCreate Controllers/HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using System;
namespace SecureApp.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Error(int? statusCode = null)
{
ViewData["StatusCode"] = statusCode ?? 500;
return View();
}
public IActionResult TestError()
{
throw new Exception("Test exception for demonstration");
}
}
}
Create Views/Home/Error.cshtml:
<h1>Error @ViewData["StatusCode"]</h1>
<p>An unexpected error occurred. Please try again later.</p>
<a asp-action="Index">Return to Home</a>
Step 4: Add Status Code PagesUpdate Program.cs:
app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}");
Step 5: Test Exception HandlingRun the application with dotnet run. Access /Home/TestError to trigger an exception and /nonexistent to see a 404 error page.
Output (Error Page):
Error 500
An unexpected error occurred. Please try again later.
[Return to Home]
This example demonstrates global exception handling and custom error pages with status code support.
Logging with ILogger & Serilog
What is Logging?
Logging captures application events, errors, and diagnostic information for monitoring and debugging. ASP.NET Core provides the ILogger interface for built-in logging, while Serilog is a popular third-party library for structured logging.
Key Features
ILogger: Built-in, lightweight logging with providers (e.g., Console, File).
Serilog: Structured logging with rich sinks (e.g., SQL Server, Seq).
Log Levels: Trace, Debug, Information, Warning, Error, Critical.
Providers/Sinks: Output logs to various destinations.
Pros, Cons, and Alternatives for Logging
Pros
ILogger:
Built-in: No external dependencies.
Simple: Easy to configure and use.
Extensible: Supports multiple providers.
Serilog:
Structured: Stores logs as structured data (e.g., JSON).
Rich Ecosystem: Supports many sinks for advanced logging.
Flexible: Allows custom enrichers and formatters.
Cons
ILogger:
Basic: Lacks advanced features like structured logging.
Limited Sinks: Fewer output options compared to Serilog.
Serilog:
Dependency: Requires additional NuGet packages.
Complexity: Steeper learning curve for advanced features.
Performance: Structured logging can impact performance.
Alternatives
NLog: Another structured logging library.
log4net: A traditional logging framework.
Application Insights: Cloud-based logging and monitoring.
Custom Logging: Build a custom logging solution for specific needs.
Example: Implementing Logging
Let’s implement logging with ILogger and Serilog in an MVC application.
Step 1: Install Serilog Packages
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File
Step 2: Configure SerilogUpdate Program.cs:
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Configure Serilog
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Step 3: Use Logging in a ControllerUpdate Controllers/HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
namespace SecureApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Index page accessed at {Time}", DateTime.Now);
return View();
}
public IActionResult Error(int? statusCode = null)
{
_logger.LogError("Error page accessed with status code {StatusCode}", statusCode ?? 500);
ViewData["StatusCode"] = statusCode ?? 500;
return View();
}
public IActionResult TestError()
{
try
{
throw new Exception("Test exception for logging");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in TestError action");
throw;
}
}
}
}
Step 4: Test LoggingRun the application and access /, /Home/TestError, and /nonexistent. Check the console and logs/app.log for log entries.
Output (Log File):
2025-08-20 16:39:00.123 +06:00 [INF] Index page accessed at 8/20/2025 4:39:00 PM
2025-08-20 16:39:05.456 +06:00 [ERR] Error in TestError action: Test exception for logging
2025-08-20 16:39:05.789 +06:00 [ERR] Error page accessed with status code 500
This example demonstrates logging with ILogger and Serilog, with structured output to console and file.
Securing Against CSRF, XSS, SQL Injection
Understanding Common Security Threats
Web applications are vulnerable to several common attacks:
CSRF (Cross-Site Request Forgery): Attackers trick users into performing unintended actions.
XSS (Cross-Site Scripting): Attackers inject malicious scripts into web pages.
SQL Injection: Attackers manipulate SQL queries to access or modify data.
Key Features
CSRF: ASP.NET Core provides anti-forgery tokens.
XSS: Built-in HTML encoding and validation.
SQL Injection: Parameterized queries and ORM (e.g., EF Core).
Pros, Cons, and Alternatives for Security
Pros
Built-in Protections: ASP.NET Core includes anti-CSRF, HTML encoding, and parameterized queries.
Configurable: Security features are easy to customize.
Compliance: Supports GDPR, OWASP, and other standards.
Cons
Complexity: Proper configuration requires understanding of threats.
Performance: Security checks can add overhead.
False Positives: Overly strict validation may block legitimate inputs.
Alternatives
Web Application Firewalls (WAF): For additional protection.
Third-Party Libraries: Use libraries like OWASP AntiSamy for XSS.
Cloud Security: Leverage Azure or AWS security services.
Example: Implementing Security Measures
Let’s secure an MVC application against CSRF, XSS, and SQL injection.
Step 1: Configure Anti-CSRFUpdate Views/Home/Index.cshtml:
<h1>Submit Form</h1>
<form asp-action="Submit" method="post">
@Html.AntiForgeryToken()
<input type="text" name="input" />
<button type="submit">Submit</button>
</form>
Update Controllers/HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
namespace SecureApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Submit(string input)
{
_logger.LogInformation("Form submitted with input: {Input}", input);
return RedirectToAction("Index");
}
}
}
Step 2: Prevent XSSUpdate Views/Home/Index.cshtml to encode user input:
<h1>Submit Form</h1>
<form asp-action="Submit" method="post">
@Html.AntiForgeryToken()
<input type="text" name="input" />
<button type="submit">Submit</button>
</form>
<div>@ViewData["Input"]</div>
Update Controllers/HomeController.cs:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Submit(string input)
{
if (string.IsNullOrEmpty(input))
{
ModelState.AddModelError("input", "Input is required");
return View("Index");
}
ViewData["Input"] = System.Web.HttpUtility.HtmlEncode(input); // Prevent XSS
_logger.LogInformation("Form submitted with input: {Input}", input);
return View("Index");
}
Step 3: Prevent SQL InjectionCreate Data/AppDbContext.cs:
using Microsoft.EntityFrameworkCore;
namespace SecureApp.Data
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<UserInput> UserInputs { get; set; }
}
public class UserInput
{
public int Id { get; set; }
public string Value { get; set; }
}
}
Update Program.cs:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
Update appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=SecureAppDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Update Controllers/HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using SecureApp.Data;
using System;
using System.Threading.Tasks;
namespace SecureApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly AppDbContext _context;
public HomeController(ILogger<HomeController> logger, AppDbContext context)
{
_logger = logger;
_context = context;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Submit(string input)
{
try
{
if (string.IsNullOrEmpty(input))
{
ModelState.AddModelError("input", "Input is required");
return View("Index");
}
var userInput = new UserInput { Value = input };
_context.UserInputs.Add(userInput);
await _context.SaveChangesAsync();
ViewData["Input"] = System.Web.HttpUtility.HtmlEncode(input);
_logger.LogInformation("Form submitted with input: {Input}", input);
return View("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error saving input");
return View("Error");
}
}
}
}
Step 4: Test SecurityRun the application and test:
Submit a form without the anti-forgery token (should fail).
Enter <script>alert('XSS');</script> (should be encoded).
Verify database queries use parameters to prevent SQL injection.
This example demonstrates protection against CSRF, XSS, and SQL injection with proper validation and encoding.
HTTPS Enforcement & Data Protection
What are HTTPS and Data Protection?
HTTPS Enforcement ensures all communication uses secure HTTPS connections. Data Protection in ASP.NET Core protects sensitive data (e.g., cookies, tokens) using encryption and key management.
Key Features
HTTPS: Enforces secure communication with TLS/SSL.
Data Protection API: Encrypts and decrypts sensitive data.
Key Management: Automatically manages encryption keys.
Pros, Cons, and Alternatives for HTTPS and Data Protection
Pros
HTTPS:
Security: Protects data in transit.
SEO: Improves search engine rankings.
Compliance: Meets standards like GDPR and PCI-DSS.
Data Protection:
Built-in: Integrated with ASP.NET Core.
Automatic: Handles key generation and rotation.
Flexible: Supports custom key storage.
Cons
HTTPS:
Cost: SSL certificates may incur costs.
Performance: Slight overhead for encryption.
Setup: Requires certificate management.
Data Protection:
Complexity: Key management can be complex in distributed systems.
Storage: Requires secure key storage.
Performance: Encryption/decryption adds overhead.
Alternatives
HTTPS: Use HTTP/2 or QUIC for performance improvements.
Data Protection: Use third-party encryption libraries (e.g., BouncyCastle).
Cloud Services: Leverage Azure Key Vault or AWS KMS for key management.
Example: Implementing HTTPS and Data Protection
Let’s enforce HTTPS and protect sensitive data in cookies.
Step 1: Enforce HTTPSUpdate Program.cs:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Configure Serilog
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDataProtection();
builder.Services.AddHsts(options =>
{
options.MaxAge = TimeSpan.FromDays(365);
options.IncludeSubDomains = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Step 2: Protect Data in CookiesUpdate Controllers/HomeController.cs:
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
namespace SecureApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IDataProtector _protector;
public HomeController(ILogger<HomeController> logger, IDataProtectionProvider provider)
{
_logger = logger;
_protector = provider.CreateProtector("SensitiveData");
}
public IActionResult SetProtectedCookie(string value)
{
try
{
var protectedValue = _protector.Protect(value);
Response.Cookies.Append("SensitiveData", protectedValue, new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict
});
_logger.LogInformation("Protected cookie set");
return RedirectToAction("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error setting protected cookie");
return View("Error");
}
}
public IActionResult GetProtectedCookie()
{
try
{
var protectedValue = Request.Cookies["SensitiveData"];
if (protectedValue != null)
{
var value = _protector.Unprotect(protectedValue);
ViewData["SensitiveData"] = value;
}
return View("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error reading protected cookie");
return View("Error");
}
}
}
}
Step 3: Update Index.cshtml
<h1>Secure App</h1>
<form asp-action="SetProtectedCookie" method="post">
@Html.AntiForgeryToken()
<input type="text" name="value" />
<button type="submit">Set Cookie</button>
</form>
<a asp-action="GetProtectedCookie">Read Cookie</a>
<div>@ViewData["SensitiveData"]</div>
Step 4: Test HTTPS and Data ProtectionRun the application with HTTPS enabled (use a self-signed certificate for development). Set and read a protected cookie to verify encryption.
This example demonstrates HTTPS enforcement and data protection for secure cookies.
Best Practices for Security, Logging, and Error Handling
Security Best Practices
Validate Inputs: Sanitize all user inputs to prevent XSS and injection attacks.
Use Anti-Forgery Tokens: Protect POST requests from CSRF.
Enforce HTTPS: Redirect all HTTP traffic to HTTPS.
Protect Data: Encrypt sensitive data with the Data Protection API.
Follow OWASP Guidelines: Adhere to OWASP Top 10 security practices.
Performance Best Practices
Optimize Logging: Use appropriate log levels to avoid overhead.
Efficient Error Handling: Minimize try-catch blocks in hot paths.
Cache Security Checks: Cache authorization results when possible.
Minimize Encryption Overhead: Use efficient algorithms for data protection.
Error Handling Best Practices
Centralized Handling: Use middleware or filters for global error handling.
Log Errors: Capture detailed error information with context.
User-Friendly Messages: Display generic messages to users, detailed logs for developers.
Retry Logic: Implement retries for transient errors (e.g., database failures).
Real-Life Example: Building a Secure E-Commerce Platform
Let’s build an e-commerce platform with secure forms, logging, error handling, and data protection.
Step 1: Set Up the ProjectUse the existing project and add a product model and database.
Create Models/Product.cs:
namespace SecureApp.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}
Update Data/AppDbContext.cs:
using Microsoft.EntityFrameworkCore;
using SecureApp.Models;
namespace SecureApp.Data
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
public DbSet<UserInput> UserInputs { get; set; }
}
}
Step 2: Update Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SecureApp.Data;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Configure Serilog
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDataProtection();
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddHsts(options =>
{
options.MaxAge = TimeSpan.FromDays(365);
options.IncludeSubDomains = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}");
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Step 3: Create a Product ControllerCreate Controllers/ProductController.cs:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using SecureApp.Data;
using SecureApp.Models;
using System;
using System.Threading.Tasks;
namespace SecureApp.Controllers
{
public class ProductController : Controller
{
private readonly AppDbContext _context;
private readonly ILogger<ProductController> _logger;
public ProductController(AppDbContext context, ILogger<ProductController> logger)
{
_context = context;
_logger = logger;
}
public async Task<IActionResult> Index()
{
try
{
var products = await _context.Products.ToListAsync();
_logger.LogInformation("Products page accessed");
return View(products);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error fetching products");
return RedirectToAction("Error", "Home");
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddProduct(Product product)
{
try
{
if (!ModelState.IsValid)
{
_logger.LogWarning("Invalid product data submitted");
return View("Index", await _context.Products.ToListAsync());
}
_context.Products.Add(product);
await _context.SaveChangesAsync();
_logger.LogInformation("Product added: {Name}", product.Name);
return RedirectToAction("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error adding product");
return RedirectToAction("Error", "Home");
}
}
}
}
Step 4: Create ViewsCreate Views/Product/Index.cshtml:
@model IEnumerable<SecureApp.Models.Product>
<h1>E-Commerce Platform</h1>
<form asp-action="AddProduct" method="post">
@Html.AntiForgeryToken()
<input type="text" name="Name" placeholder="Product Name" required />
<input type="number" name="Price" placeholder="Price" step="0.01" required />
<button type="submit">Add Product</button>
</form>
<ul>
@foreach (var product in Model)
{
<li>@Html.Raw(System.Web.HttpUtility.HtmlEncode(product.Name)) - $@product.Price</li>
}
</ul>
Step 5: Seed DataAdd to Program.cs:
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
context.Products.AddRange(
new Models.Product { Name = "Laptop", Price = 999.99m },
new Models.Product { Name = "Smartphone", Price = 499.99m }
);
await context.SaveChangesAsync();
}
Step 6: Test the ApplicationRun the application with HTTPS enabled. Test:
Adding products (CSRF protection).
Viewing products (XSS prevention with HTML encoding).
Database operations (SQL injection prevention with EF Core).
Error handling (custom error pages and logging).
Protected cookies (data protection API).
Real-Life Scenario: This e-commerce platform demonstrates:
Exception Handling: Custom error pages for user-friendly feedback.
Logging: Structured logging with Serilog for monitoring.
Security: Protection against CSRF, XSS, and SQL injection.
HTTPS/Data Protection: Secure communication and data storage.
Conclusion
In Module 11 of our ASP.NET Core Complete Course, we explored Security, Logging, and Error Handling, covering:
Handling Exceptions & Custom Error Pages: Graceful error management.
Logging with ILogger & Serilog: Capturing application events.
Securing Against CSRF, XSS, SQL Injection: Protecting against vulnerabilities.
HTTPS Enforcement & Data Protection: Ensuring secure communication and data storage.
Through practical examples and a real-life e-commerce platform, you’ve learned how to implement these features with best practices for security, performance, and error handling. In the next module, we’ll explore deployment, testing, and advanced optimization techniques. Stay tuned!
FAQs
Q1: Why is exception handling important in ASP.NET Core?
It prevents crashes, improves user experience, and aids debugging with detailed logs.
Q2: How does Serilog improve logging over ILogger?
Serilog offers structured logging, rich sinks, and advanced customization.
Q3: How can I protect my ASP.NET Core app from CSRF?
Use anti-forgery tokens and validate them in POST requests.
Q4: What is the Data Protection API used for?
It encrypts and decrypts sensitive data, such as cookies or tokens.
Q5: Why enforce HTTPS in web applications?
HTTPS secures data in transit, improves SEO, and ensures compliance.
No comments:
Post a Comment
Thanks for your valuable comment...........
Md. Mominul Islam