Unit 4: Asp.Net MVC and Security
I. Foundations of ASP.NET Core MVC
ASP.NET Core MVC is a cross-platform framework for building web applications and APIs using the Model–View–Controller pattern. It combines an HTTP request pipeline, middleware, dependency injection, Entity Framework Core data access, routing, model binding, authentication, and authorization.
- Model–View–Controller convention:
- Model: Represents application data and business rules, such as a
Studententity. - View: Renders the user interface, usually through Razor
.cshtmlfiles. - Controller: Receives HTTP requests and coordinates models, services, and views.
- Model: Represents application data and business rules, such as a
- Request-based operation: A client sends an HTTP request; ASP.NET Core processes it through middleware before an endpoint generates an HTTP response.
- Configuration model: Application services and the request pipeline are normally configured in
Program.cs. - Asynchronous execution: Framework operations commonly use
asyncandawaitto avoid blocking threads during database or network access. - Security principle: Applications must establish who the user is through authentication and determine permitted actions through authorization.
- Data-access convention: Entity Framework Core maps .NET classes to relational database tables and supports both Code First and Database First development.
II. ASP.NET Core Request Processing — The Middleware Pipeline
A. Middleware Request Pipeline
The middleware request pipeline is an ordered sequence of components that processes every HTTP request and response.
- Middleware component: A middleware component receives an
HttpContextand may perform work before and after invoking the next component. - Pipeline direction:
- Requests travel through middleware in registration order.
- Responses travel back through previously invoked middleware in reverse order.
- Request delegate:
RequestDelegaterepresents the next pipeline operation and accepts anHttpContext. - Continue or terminate:
Usecan invokenext()and continue processing.Runusually terminates the pipeline by generating the response directly.
- Branching:
MapandMapWhencreate separate pipelines for matching paths or conditions. - Order dependence: Exception handling should generally appear early, while authentication must execute before authorization.
var app = builder.Build();
app.UseExceptionHandler("/Home/Error");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();- Concrete flow: A request for
/Products/Details/5passes through exception handling, HTTPS redirection, static-file checking, routing, authentication, and authorization before reachingProductsController.Details(5). - Endpoint execution:
MapControllerRoutemaps controller endpoints;app.Run()starts the application and completes pipeline configuration.
III. Middleware Components — Framework and User-Defined Processing
A. Built-In Middleware and Custom Middleware
Built-in middleware provides standard framework behavior, while custom middleware implements application-specific request processing.
-
Built-in middleware
- Static files:
UseStaticFiles()serves files fromwwwroot, such as/css/site.css. - Routing:
UseRouting()identifies the endpoint matching the request URL. - Security:
UseAuthentication()establishes identity, andUseAuthorization()enforces access rules. - Error handling:
UseExceptionHandler()produces controlled error responses in production. - HTTPS enforcement:
UseHttpsRedirection()redirects HTTP requests to HTTPS. - Session support:
UseSession()enables server-side session state after session services are registered.
- Static files:
-
Custom middleware
- Purpose: It handles concerns such as request logging, correlation IDs, timing, custom headers, or tenant detection.
- Structure: A conventional middleware class has a constructor accepting
RequestDelegateand anInvokeAsyncmethod acceptingHttpContext.
public class TimingMiddleware
{
private readonly RequestDelegate _next;
public TimingMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var start = DateTime.UtcNow;
await _next(context);
var elapsed = DateTime.UtcNow - start;
context.Response.Headers["X-Time-Ms"] =
elapsed.TotalMilliseconds.ToString("F0");
}
}app.UseMiddleware<TimingMiddleware>();- Short-circuiting: A custom component can omit
await _next(context)and return a response immediately, for example when an API key is absent. - Constraint: Response headers must normally be set before the response body begins.
IV. Dependency Management — Inversion of Control
A. Dependency Injection (DI)
Dependency Injection supplies an object’s dependencies externally instead of requiring the object to construct them itself.
- Dependency example:
ProductsControllermay depend onIProductServicerather than directly creatingProductService. - Inversion of control: Object creation is transferred to a container, reducing coupling between consumers and implementations.
- Constructor injection: Required dependencies are declared as constructor parameters, making them explicit and testable.
public class ProductsController : Controller
{
private readonly IProductService _service;
public ProductsController(IProductService service)
{
_service = service;
}
}- Service abstraction: An interface such as
IProductServicepermits replacement with another implementation or a test double. - Service lifetimes:
- Transient: A new instance is created whenever requested.
- Scoped: One instance is used within an HTTP request;
DbContextnormally uses this lifetime. - Singleton: One instance exists for the application lifetime.
- Lifetime safety: A singleton must not directly depend on a scoped service because the scoped object could outlive its valid request scope.
- Benefits: DI improves modularity, unit testing, maintainability, and centralized lifecycle management.
V. Service Registration — Using the ASP.NET Core Container
A. Implementing DI in ASP.NET Core
ASP.NET Core implements DI through the service collection configured during application startup and the service provider used at runtime.
- Service registration: Services are added to
builder.Servicesbeforebuilder.Build().
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddScoped<IProductService, ProductService>();
builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.AddSingleton<ISystemClock, SystemClock>();
var app = builder.Build();- Resolution: When MVC creates
ProductsController, the container identifies its constructor parameters and resolves the registered implementations. - Framework services: Calls such as
AddControllersWithViews(),AddDbContext<T>(), andAddAuthentication()register groups of related services. - Multiple dependencies: A controller can request services such as
ILogger<ProductsController>,AppDbContext, andIProductServicethrough its constructor. - Configuration injection: The options pattern provides strongly typed settings.
builder.Services.Configure<MailSettings>(
builder.Configuration.GetSection("MailSettings"));- Preferred practice: Depend on narrow interfaces rather than retrieving services through
HttpContext.RequestServices. - Limitation: Registering an implementation without its required dependencies causes a runtime service-resolution exception.
VI. Entity Framework Core — Model-Driven Database Development
A. Developing Application with Code First Approach
Code First begins with C# entity classes and uses migrations to create and evolve the database schema.
- Entity definition: A class represents a table, while properties generally represent columns.
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public decimal Price { get; set; }
}- Database context:
DbContextcoordinates entity mapping, querying, change tracking, and persistence.
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
public DbSet<Product> Products => Set<Product>();
}- Registration:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));- Migrations workflow:
dotnet ef migrations add InitialCreategenerates migration operations.dotnet ef database updateapplies them to the configured database.
- CRUD operation:
context.Products.Add(product)marks an entity as added;await context.SaveChangesAsync()issues the correspondingINSERT. - Mapping control: Data annotations such as
[Required]and Fluent API calls inOnModelCreatingdefine constraints and relationships. - Advantages: The model remains source-controlled, schema changes are repeatable, and development can begin before a database exists.
- Limitation: Careless migration changes may cause data loss, so production migrations require review and backup planning.
VII. Entity Framework Core — Existing-Database Development
A. Developing Application with Database First Approach
Database First begins with an existing database and reverse-engineers entity classes and a DbContext from its schema.
- Scaffolding command: EF Core tools inspect tables, primary keys, foreign keys, column types, and relationships.
dotnet ef dbcontext scaffold \
"Server=.;Database=ShopDb;Trusted_Connection=True;TrustServerCertificate=True" \
Microsoft.EntityFrameworkCore.SqlServer \
--context ShopDbContext --output-dir Models- Generated output: A
Productstable may produce aProductentity and aDbSet<Product>property inShopDbContext. - Required packages: The project typically needs the database provider,
Microsoft.EntityFrameworkCore.Design, and thedotnet-eftool. - Schema updates: When the database changes, models may be re-scaffolded; custom code should be placed in partial classes or separate files to avoid overwriting.
- Connection security: Connection strings should be stored in configuration, environment variables, or secret storage rather than committed in source code.
- Advantages: The approach suits legacy databases, DBA-controlled schemas, and applications integrating with established data.
- Limitations: Re-scaffolding can overwrite generated code, and unsupported database objects may require manual mapping.
- Explicit contrast:
- Code First: C# model changes drive database migrations.
- Database First: Existing database schema drives generated C# models.
VIII. Application Security — Identity and Access Control
A. Authentication and Authorization in Web Application
Authentication verifies a user’s identity, whereas authorization decides which resources that authenticated identity may access.
- Authentication
- Identity establishment: A successful sign-in creates a
ClaimsPrincipalcontaining claims such as name, role, or user identifier. - Cookie authentication: Common in MVC applications; the browser sends an encrypted authentication cookie with later requests.
- Bearer authentication: APIs commonly accept a JWT bearer token in the
Authorizationheader. - Configuration:
- Identity establishment: A successful sign-in creates a
builder.Services.AddAuthentication("Cookies")
.AddCookie("Cookies", options =>
options.LoginPath = "/Account/Login");- Authorization
- Controller protection:
[Authorize]requires an authenticated user, while[AllowAnonymous]permits public access. - Role-based rule:
[Authorize(Roles = "Admin")]restricts an action to an identity carrying theAdminrole. - Policy-based rule:
- Controller protection:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdultOnly",
policy => policy.RequireClaim("Age", "18"));
});[Authorize(Policy = "AdultOnly")]
public IActionResult Restricted() => View();- Pipeline requirement:
UseAuthentication()must appear beforeUseAuthorization(). - Defense in depth: Authorization must be enforced on server endpoints, not merely by hiding buttons in a view.
- Supporting protections: HTTPS protects credentials in transit; anti-forgery tokens reduce CSRF risk in cookie-based forms; secure password hashing protects stored credentials.
- Access outcomes: An unauthenticated user is typically challenged to sign in, whereas an authenticated user lacking permission receives a forbidden response.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →