Unit 4: Asp.Net MVC and Security - Subjective Questions
INT402 — Modern Web Programming Tools And Techniques • Practice Questions with Detailed Answers
20 questions
Define the middleware request pipeline in ASP.NET Core. Explain how an HTTP request and response travel through the pipeline.
The middleware request pipeline is an ordered sequence of software components that process HTTP requests and responses in an ASP.NET Core application.
- An incoming HTTP request is passed to the first middleware component.
- Each component can inspect or modify the request.
- A component may invoke the next middleware by calling
await next(context). - After downstream processing is complete, the response travels back through the middleware components in reverse order.
- Middleware can also terminate the pipeline early by generating a response without invoking the next component. This is called short-circuiting.
The pipeline is normally configured in Program.cs by using methods such as Use, Run, and Map. The order in which middleware is registered is important because it determines the order of request processing and the reverse order of response processing.
Distinguish between the Use, Run, and Map methods used to configure the ASP.NET Core request pipeline.
The three methods serve different purposes in middleware configuration:
Use: Adds middleware that can perform work before and after the next component. It normally receives anextdelegate and may call it to continue processing.Run: Adds terminal middleware. It handles the request and does not provide anextdelegate, so no later middleware is executed.Map: Creates a pipeline branch based on a request path. For example,app.Map("/admin", ...)processes requests beginning with/adminthrough a separate branch.
Therefore, Use supports pipeline continuation, Run terminates processing, and Map conditionally branches the pipeline according to the URL path.
Explain why the order of middleware components is important in an ASP.NET Core application. Give suitable examples.
Middleware is executed in the order in which it is registered for requests and in reverse order for responses. An incorrect order can cause functionality or security failures.
A typical order is:
- Exception handling
- HTTPS redirection
- Static files
- Routing
- Authentication
- Authorization
- Endpoint execution
Important examples include:
UseRouting()must execute before middleware that depends on endpoint information.UseAuthentication()must execute beforeUseAuthorization()because authorization needs the authenticated user identity.UseAuthorization()must execute before mapped controllers or endpoints.- Static-file middleware can be placed early so files are returned without unnecessary MVC processing.
- Exception-handling middleware should appear early so it can catch exceptions raised by later components.
Thus, middleware order directly affects correctness, performance, and security.
Describe any five commonly used built-in middleware components in ASP.NET Core and state the purpose of each.
Common built-in middleware components include:
- Exception Handler Middleware: Catches unhandled exceptions and produces a controlled error response in production.
- Static File Middleware: Serves files such as CSS, JavaScript, images, and HTML from the configured web root.
- HTTPS Redirection Middleware: Redirects HTTP requests to HTTPS to improve transport security.
- Routing Middleware: Matches an incoming request with an application endpoint.
- Authentication Middleware: Examines authentication data, such as cookies or tokens, and constructs the user's identity.
- Authorization Middleware: Determines whether the authenticated user is allowed to access the selected resource.
- CORS Middleware: Applies cross-origin resource-sharing rules to requests from different origins.
Each component handles a specific cross-cutting concern and can be combined with others to construct the complete request pipeline.
What is custom middleware? Describe the steps required to create and register a class-based custom middleware component in ASP.NET Core.
Custom middleware is an application-defined component that processes HTTP requests and responses for concerns such as logging, timing, custom headers, or tenant identification.
The main steps are:
- Create a middleware class.
- Accept a
RequestDelegatethrough its constructor and store it. - Define an
InvokeorInvokeAsyncmethod that acceptsHttpContext. - Perform request-side processing before calling the next component.
- Call
await _next(context)unless the middleware must terminate the pipeline. - Perform response-side processing after the call returns.
- Register the component in
Program.cswithapp.UseMiddleware<CustomMiddleware>().
Services required by the middleware can be supplied through dependency injection. Constructor injection is suitable for singleton-compatible dependencies, while scoped services are commonly injected into InvokeAsync.
Develop a custom ASP.NET Core middleware component that measures request-processing time. Explain its operation and registration.
A timing middleware can use Stopwatch to measure the time taken by downstream components:
public class RequestTimingMiddleware
{
private readonly RequestDelegate _next;
public RequestTimingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, ILogger<RequestTimingMiddleware> logger)
{
var timer = Stopwatch.StartNew();
await _next(context);
timer.Stop();
logger.LogInformation("Request {Path} completed in {Elapsed} ms", context.Request.Path, timer.ElapsedMilliseconds);
}
}
It is registered using app.UseMiddleware<RequestTimingMiddleware>();.
- The timer starts before downstream middleware is invoked.
await _next(context)passes control to the rest of the pipeline.- When processing returns, the timer is stopped.
- The elapsed time is recorded through the logging service.
- Its registration position determines which downstream operations are included in the measurement.
Define Dependency Injection (DI). Explain the roles of service registration, the service container, and service resolution in ASP.NET Core.
Dependency Injection is a design technique in which an object's dependencies are supplied from outside instead of being created by the object itself.
ASP.NET Core implements DI through three main activities:
- Service registration: Services are associated with interfaces or concrete types in
builder.Services, usually inProgram.cs. - Service container: The framework builds a container that stores service descriptors and controls object creation and disposal.
- Service resolution: When ASP.NET Core creates a controller, middleware component, or other managed object, it resolves the required constructor parameters from the container.
DI provides:
- Reduced coupling between components
- Easier unit testing through mock implementations
- Centralized object creation and configuration
- Consistent lifetime management
- Easier replacement of service implementations
Compare the Transient, Scoped, and Singleton service lifetimes in ASP.NET Core. Give an appropriate use case for each.
ASP.NET Core supports three principal service lifetimes:
- Transient: A new instance is created every time the service is requested. It is appropriate for lightweight, stateless services such as formatters or validators. It is registered with
AddTransient. - Scoped: One instance is created for each HTTP request and shared within that request. It is appropriate for request-related business services and Entity Framework Core
DbContextobjects. It is registered withAddScoped. - Singleton: One instance is created and shared for the entire application lifetime. It is appropriate for thread-safe configuration providers, caches, or services that maintain application-wide state. It is registered with
AddSingleton.
A singleton must not directly depend on a scoped service because the scoped object could be retained beyond its intended request lifetime. Singleton implementations must also be designed for concurrent access.
Explain how to implement constructor-based dependency injection in an ASP.NET Core MVC controller with a suitable example.
Constructor injection declares required dependencies as constructor parameters. ASP.NET Core resolves those parameters when it creates the controller.
First, define and implement a service:
public interface IProductService
{
Task<IEnumerable<Product>> GetAllAsync();
}
public class ProductService : IProductService
{
public Task<IEnumerable<Product>> GetAllAsync() { /* implementation */ }
}
Register it in Program.cs:
builder.Services.AddScoped<IProductService, ProductService>();
Inject it into a controller:
public class ProductsController : Controller
{
private readonly IProductService _service;
public ProductsController(IProductService service)
{
_service = service;
}
}
The controller depends on the abstraction IProductService, while the container supplies ProductService. This improves modularity and enables a fake or mock service to be supplied during unit testing.
Discuss common dependency-injection mistakes in ASP.NET Core, including the service locator pattern, captive dependencies, and incorrect disposal.
Common DI mistakes include:
- Service locator pattern: Repeatedly calling
IServiceProvider.GetServicehides a class's dependencies and makes testing difficult. Constructor injection should normally be used. - Captive dependency: A singleton captures a scoped or transient dependency and keeps it longer than intended. This can cause stale state, concurrency problems, or reuse of a disposed object.
- Manual disposal: Services created and managed by the container should normally be disposed by the container. Manually disposing them may break later consumers.
- Heavy constructors: Constructors should receive dependencies but should not perform expensive I/O or long-running work.
- Excessive dependencies: A controller requiring many services may be handling too many responsibilities and should be redesigned.
- Thread-unsafe singleton state: Singleton services are shared across requests and must protect mutable state.
Correct lifetime selection and explicit constructor dependencies are essential for reliable DI usage.
What is the Code First approach in Entity Framework Core? Describe the complete process for creating a database from model classes.
In the Code First approach, developers define entity classes and their relationships in code, and Entity Framework Core uses that model to create or update the database schema.
The process is:
- Install the required Entity Framework Core provider and tooling packages.
- Create entity classes, such as
StudentandCourse. - Create a class derived from
DbContext. - Expose entities through
DbSet<TEntity>properties. - Configure relationships and constraints using data annotations or the Fluent API.
- Store the connection string in configuration.
- Register the context with
AddDbContextand the required database provider. - Create a migration using
dotnet ef migrations add InitialCreate. - Apply it using
dotnet ef database update.
EF Core compares later model changes with its model snapshot and generates additional migrations. This allows schema changes to be versioned along with application code.
Explain the purpose of DbContext, DbSet<TEntity>, connection strings, and database providers in an Entity Framework Core application.
These elements have distinct responsibilities:
DbContext: Represents a session with the database. It manages database connections, queries, change tracking, transactions, and persistence throughSaveChangesorSaveChangesAsync.DbSet<TEntity>: Represents a collection of entities of a particular type. It is used to query, add, update, or remove entity records.- Connection string: Contains information required to connect to the database, such as the server, database name, and authentication settings. It is commonly stored in
appsettings.jsonor a secure configuration source. - Database provider: Translates EF Core operations into commands for a specific database system, such as SQL Server, SQLite, or PostgreSQL.
Together, these components connect the object model to the selected relational database and allow data access through .NET classes and LINQ.
Describe Entity Framework Core migrations. How are migrations created, applied, rolled back, and maintained in a team project?
Migrations are versioned descriptions of database-schema changes derived from modifications to the EF Core model.
Important operations include:
- Create a migration with
dotnet ef migrations add MigrationName. - Apply pending migrations with
dotnet ef database update. - Roll back by updating to an earlier migration with
dotnet ef database update PreviousMigration. - Remove the latest unapplied migration with
dotnet ef migrations remove. - Generate a deployment script with
dotnet ef migrations script.
A migration normally contains an Up method for applying changes and a Down method for reversing them. EF Core also maintains a model snapshot.
In a team project, migration files should be committed to source control. Developers should review generated operations, coordinate changes to avoid conflicts, test migrations against representative databases, and use reviewed scripts or controlled deployment processes in production.
What is the Database First approach in Entity Framework Core? Explain how an existing database can be reverse-engineered into an ASP.NET Core application.
The Database First approach begins with an existing database. Entity Framework Core reverse-engineers the database schema to generate entity classes and a DbContext.
The process is:
- Install the required EF Core database provider and design-time tools.
- Ensure that the existing database has appropriate tables, primary keys, foreign keys, and constraints.
- Run a scaffolding command such as
dotnet ef dbcontext scaffoldwith the connection string and provider. - Optionally specify output folders, selected tables, context name, namespaces, or data-annotation generation.
- Register the generated context with ASP.NET Core DI.
- Inject the context or repository services into application components.
- Query and modify data using the generated entities.
The generated model reflects database tables, columns, keys, and relationships. Connection strings should be moved to secure configuration rather than embedded in generated source code.
Compare the Code First and Database First approaches. State the advantages, limitations, and suitable use cases of each.
Code First begins with application classes, whereas Database First begins with an existing database schema.
Code First:
- The domain model is controlled in source code.
- Migrations provide versioned schema evolution.
- It works well for new applications and domain-driven development.
- Developers can design entities and relationships using C#.
- It may be unsuitable when a database is controlled by a separate database administration team.
Database First:
- Models are generated from an existing schema.
- It is suitable for legacy databases, shared enterprise databases, or database-centered development.
- It quickly reflects existing tables, keys, and relationships.
- Re-scaffolding may overwrite generated customizations.
- Database changes must be coordinated before generated models are refreshed.
The choice depends on whether the application model or the existing database is the primary source of truth.
Explain how entity relationships are represented in Entity Framework Core. Discuss one-to-one, one-to-many, and many-to-many relationships.
Entity Framework Core represents relationships through primary keys, foreign keys, and navigation properties.
- One-to-one: One entity is associated with exactly one related entity. For example, one
Usermay have oneUserProfile. A unique foreign key identifies the dependent entity. - One-to-many: One principal entity has many dependent entities. For example, one
Departmentmay contain manyEmployees. The dependent entity stores the foreign key. - Many-to-many: Multiple entities on both sides may be related. For example, many
Studentsmay join manyCourses. EF Core can create an implicit join table, or an explicit join entity can be used when the relationship contains additional data.
Relationships can be configured through conventions, data annotations, or the Fluent API in OnModelCreating. The Fluent API provides the greatest control over foreign keys, required relationships, delete behavior, and constraint names.
Distinguish between authentication and authorization in a web application. Explain how they are related.
Authentication determines who the user is, while authorization determines what that user is allowed to do.
- Authentication validates credentials or tokens and creates a
ClaimsPrincipalrepresenting the user. - Authorization evaluates that identity against access rules such as roles, claims, policies, or resource-specific requirements.
- Authentication normally occurs before authorization in the middleware pipeline.
- A user who is not authenticated may receive an authentication challenge, such as a redirect to a login page or a
401 Unauthorizedresponse. - An authenticated user who lacks permission normally receives a
403 Forbiddenresponse.
For example, signing in with a username and password is authentication. Checking whether the signed-in user has the Administrator role before opening an administration page is authorization.
Describe cookie-based authentication and token-based authentication in ASP.NET Core. Compare their typical uses and security considerations.
Cookie-based authentication stores an encrypted authentication ticket in a browser cookie. The browser automatically sends the cookie with matching requests. It is commonly used by server-rendered MVC applications.
Token-based authentication, commonly using a bearer token such as a JWT, sends a token in the HTTP Authorization header. It is frequently used by web APIs, mobile applications, and distributed clients.
Key differences and considerations are:
- Cookies are automatically submitted by browsers and therefore require protection against CSRF.
- Bearer tokens are explicitly attached by clients but can be stolen through XSS or insecure storage.
- Cookies should use
HttpOnly,Secure, and an appropriateSameSitesetting. - Tokens should have short lifetimes, validated signatures, correct issuer and audience values, and a secure refresh strategy.
- Both approaches require HTTPS.
- Sensitive credentials or tokens should not be exposed in URLs, logs, or client-accessible storage unnecessarily.
Explain role-based, claims-based, and policy-based authorization in ASP.NET Core. Provide a suitable scenario for each.
ASP.NET Core supports several authorization models:
- Role-based authorization checks whether the user belongs to a named role. For example,
[Authorize(Roles = "Administrator")]can protect an administration controller. - Claims-based authorization checks facts associated with the user, such as department, country, age, or employee number. For example, access may require a
Departmentclaim with the valueFinance. - Policy-based authorization groups one or more requirements into a named policy. A policy can require authentication, roles, claims, or custom handlers. For example, an
CanApproveExpensepolicy may require theManagerrole and an approval-limit claim.
Policy-based authorization is the most flexible option because it centralizes reusable business rules and can support custom requirement handlers and resource-based decisions.
Design a secure authentication and authorization flow for an ASP.NET Core MVC application. Include service configuration, middleware order, access control, and major security precautions.
A secure flow can be designed as follows:
- Register MVC, the application database context, ASP.NET Core Identity or another authentication handler, and required authorization policies.
- Configure secure cookies or bearer-token validation, including expiration and validation rules.
- Add exception handling, HTTPS redirection, static files, and routing middleware.
- Call
UseAuthentication()after routing so the application can construct the user's identity. - Call
UseAuthorization()after authentication and before endpoint execution. - Protect controllers or actions with
[Authorize], role restrictions, or named policies. - Use
[AllowAnonymous]only for deliberately public actions such as login. - Validate anti-forgery tokens for state-changing browser requests.
- Apply account lockout, secure password hashing, multifactor authentication where appropriate, and safe session expiration.
- Store secrets outside source code, use HTTPS, validate input, encode output, and record security-relevant events without logging credentials or tokens.
This design separates identity verification from access decisions and applies defense in depth across transport, middleware, endpoints, data, and credential management.
Define the middleware request pipeline in ASP.NET Core. Explain how an HTTP request and response travel through the pipeline.
The middleware request pipeline is an ordered sequence of software components that process HTTP requests and responses in an ASP.NET Core application.
- An incoming HTTP request is passed to the first middleware component.
- Each component can inspect or modify the request.
- A component may invoke the next middleware by calling
await next(context). - After downstream processing is complete, the response travels back through the middleware components in reverse order.
- Middleware can also terminate the pipeline early by generating a response without invoking the next component. This is called short-circuiting.
The pipeline is normally configured in Program.cs by using methods such as Use, Run, and Map. The order in which middleware is registered is important because it determines the order of request processing and the reverse order of response processing.
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 →