Q1. What is .NET / .NET Core?
.NET Core was the cross-platform, high-performance generation of .NET introduced as the successor to the .NET Framework. Starting with .NET 5, Microsoft unified the platform and dropped the "Core" name, so today we generally refer to it simply as .NET.
Q2. What is CLR, and how does it work?
CLR (Common Language Runtime) is the execution environment of .NET applications. It is responsible for running managed code and providing services such as memory management, garbage collection, exception handling, thread management, type safety, and security.
In simple terms, CLR is the runtime that takes the compiled .NET code and manages its execution. The execution flow is:
C# Source Code ↓ C# Compiler ↓ IL / CIL (Intermediate Language) ↓ CLR loads the assembly ↓ JIT Compiler ↓ Native Machine Code ↓ CPU executes
Q3. What is the difference between CLR and CTS?
| CLR | CTS |
|---|---|
| Runtime execution environment | Type system specification |
| Runs managed .NET code | Defines rules for .NET types |
| Handles GC, exceptions, threading, JIT, etc. | Defines types such as Int32, String, Object, classes, structs, interfaces, etc. |
| Responsible for execution and management | Responsible for type consistency and interoperability |
| Works at runtime | Defines the type rules followed by .NET languages |
Q4. How Garbage Collection works in .Net Core?
Object Created ↓ Managed Heap ↓ Object becomes unreachable ↓ GC identifies it as garbage ↓ GC collects it ↓ Memory is reclaimed
- Gen 0 → Newly allocated, short-lived objects
- Gen 1 → Objects that survived a Gen 0 collection
- Gen 2 → Long-lived objects
Q5. What is the difference between Dispose() and Garbage Collection?
| Dispose() | Garbage Collection |
|---|---|
| Manual/deterministic cleanup | Automatic memory cleanup |
| Implemented through IDisposable | Managed by the .NET GC |
| Used mainly to release unmanaged/external resources | Reclaims memory of unreachable managed objects |
| Happens when code calls Dispose() or uses using | Happens automatically when GC determines collection is needed |
| Timing is predictable | Timing is non-deterministic |
| Does not directly free managed object memory | Reclaims managed heap memory |
We can manually request Garbage Collection in .NET usingGC.Collect(), but it is generally not recommended in normal application code. The .NET GC is optimized to determine when collection is beneficial, so forcing a collection can negatively impact performance.
Q6. What is Kestrel, and what are the advantages of Kestrel in ASP.NET Core?
Kestrel is the default cross-platform web server for ASP.NET Core applications.
It is responsible for:
- Listening for incoming HTTP/HTTPS requests
- Accepting connections from clients
- Processing HTTP requests
- Passing requests into the ASP.NET Core middleware pipeline
- Sending the HTTP response back to the client
The major advantages of the Kestrel server are high performance, lightweight architecture, cross-platform support, container and cloud friendliness, support for HTTPS, WebSockets, HTTP/2 and HTTP/3, and the ability to run standalone or behind a reverse proxy such as IIS or Nginx.
Example: A client sends an HTTP request to Kestrel. Kestrel accepts the network connection and forwards the request into the ASP.NET Core middleware pipeline. The request then reaches routing, authentication, authorization, controllers or endpoints, and the response travels back through the middleware pipeline to Kestrel, which sends it back to the client.
Q7. What is the difference between IIS and Kestrel? Why do we need two web servers?
Kestrel is the cross-platform web server used by ASP.NET Core to handle HTTP/HTTPS requests and run the ASP.NET Core application. IIS is a Windows web server that can be used as a reverse proxy or hosting layer in front of an ASP.NET Core application.
We don't necessarily need both. Kestrel can run the application directly, which is common in containers, Linux, and cloud-native environments. In a traditional Windows enterprise environment, we may put IIS in front of Kestrel to use IIS features such as Windows integration, request filtering, logging, TLS handling, and reverse-proxy capabilities.
IIS and Kestrel have different responsibilities, and using both is an architectural choice rather than an ASP.NET Core requirement.
IIS vs Kestrel Server:
| # | IIS | Kestrel |
|---|---|---|
| Platform | Windows-only web server | Cross-platform: Windows, Linux, macOS |
| Role | Can act as a front-end web server / reverse proxy | Primarily the HTTP server for ASP.NET Core |
| Hosting | Can host ASP.NET Core through IIS hosting models | Directly hosts ASP.NET Core applications |
| Architecture | Often sits in front of Kestrel in traditional Windows deployments | Can run standalone or behind IIS/Nginx/load balancer |
| Main Strength | Windows integration, authentication, process management, request filtering, logging | Lightweight, high-performance, cloud/container-friendly, cross-platform |
However, Kestrel doesn’t provide all the rich functionality of a full-fledged web server such as IIS, Nginx, or Apache. Hence, we typically use it as an application server, with one of the above servers acting as a reverse proxy.
Q8. What is the purpose of launchSettings.json in asp.NET Core?
launchSettings.json is used to define the local development and debugging configuration of an ASP.NET Core application. It is mainly used by Visual Studio, Visual Studio Code, and the dotnet run command to configure things like application URLs/ports, HTTP/HTTPS settings, environment variables, and launch profiles.
It is intended primarily for development, not production deployment. The settings in launchSettings.json generally should not be relied upon for production configuration.
Example:
{ "profiles": { "MyApi": { "commandName": "Project", "applicationUrl": "https://localhost:7001;http://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
Q9. What is Generic Host or HostBuilder in .NET Core?
The Generic Host is the infrastructure that provides the lifetime, configuration, dependency injection, logging, and environment management for a .NET application.
It was introduced to provide a common hosting model not only for ASP.NET Core web applications, but also for background services, worker services, console applications, and other long-running applications.
HostBuilder is the mechanism used to configure and build this Generic Host. In modern .NET, this is usually done through Host.CreateApplicationBuilder() or WebApplication.CreateBuilder() rather than manually creating a HostBuilder.
The Generic Host brings together:
- Dependency Injection → Registers and resolves services
-
Configuration →
appsettings.json, environment variables, command-line arguments, etc. - Logging → Configures application logging
- Environment → Development, Staging, Production
- Application Lifetime → Start, run, and graceful shutdown
-
Hosted Services →
IHostedService/BackgroundService
var builder = WebApplication.CreateBuilder(args); builder.Services.AddScoped<IOrderService, OrderService>(); var app = builder.Build(); app.MapGet("/orders", () => "Orders"); app.Run();
WebApplication.CreateBuilder() sets up the host and application infrastructure, including configuration, logging, dependency injection, and hosting.Q10. What is the purpose of the .csproj file?
The .csproj file is the project configuration file for a .NET application. It defines how the project is built, compiled, packaged, and managed.
It contains important information such as the target .NET version, NuGet package dependencies, project references, build settings, output type, and other MSBuild properties.
Example:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net10.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Swashbuckle.AspNetCore" Version="..." /> </ItemGroup> <ItemGroup> <ProjectReference Include="../MyLibrary/MyLibrary.csproj" /> </ItemGroup> </Project>
TargetFramework→ Specifies which .NET version the application targets.-
PackageReference→ Defines NuGet dependencies. -
ProjectReference→ References another project. -
PropertyGroup→ Defines build/compiler settings. -
SDK → Specifies the project SDK, such as
Microsoft.NET.Sdk.Web.
Q11. What is the "Startup" class in ASP.NET Core before ASP.NET Core 6?
- Configure(): The Configure() method is used to add essential middleware(s) to the application request pipeline.
- ConfigureServices(): The ConfigureServices() method is used to add services to the IoC container.
Q12. What does WebApplication.CreateBuilder() do?
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddScoped<IOrderService, OrderService>(); var app = builder.Build(); app.UseAuthorization(); app.MapControllers(); app.Run();
Q13. What is Middleware?
- Generate an HTTP response for an incoming HTTP request
- Intercept and make changes to an incoming HTTP request and pass it on to the next piece of middleware.
- Intercept and make changes to an outgoing HTTP response and pass it on to the next piece of middleware.
Middleware can be used for common cross-cutting concerns such as:
- Authentication
- Authorization
- Exception handling
- Logging
- CORS
- HTTPS redirection
- Request/response modification
- Static files
next().public class RequestLoggingMiddleware { private readonly RequestDelegate _next; public RequestLoggingMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // Before the next middleware Console.WriteLine($"Request: {context.Request.Method} {context.Request.Path}"); await _next(context); // After the next middleware Console.WriteLine($"Response: {context.Response.StatusCode}"); } }
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseMiddleware<RequestLoggingMiddleware>(); app.MapControllers(); app.Run();
await _next(context);
Q14. What is the difference between IApplicationBuilder.Use() and IApplicationBuilder.Run()?
Use() and Run() are both used to add middleware to the ASP.NET Core request pipeline, but the key difference is that Use() can call the next middleware, while Run() is terminal and does not have a next middleware.Q15. What is the use of the "Map" extension while adding middleware to the ASP.NET Core pipeline?
Map() is used to create a separate branch in the ASP.NET Core middleware pipeline based on the request path. When the incoming request path matches the specified path, ASP.NET Core executes the middleware registered inside that branch instead of continuing through the main pipeline.app.Map("/admin", adminApp => { adminApp.Run(async context => { await context.Response.WriteAsync("Admin Area"); }); }); app.Run(async context => { await context.Response.WriteAsync("Main Application"); });
/admin/users
↓
Map("/admin")
↓
Admin branch
- Creating separate pipelines for different URL paths
- Admin-specific middleware
- API-specific middleware
- Separating different application areas
Tip: Easy way to remember:
- Use → Continue the pipeline
- Run → End the pipeline
- Map → Branch the pipeline based on the path
Q16. What is the right order of middleware used in production-level applications?
There is no single universal middleware order for every ASP.NET Core application, but middleware order is critical because each middleware runs in the order it is registered. In a typical production Web API, the pipeline commonly starts with exception handling, then HTTPS/security-related middleware, routing, CORS, authentication, authorization, and finally endpoint mapping.
Q17. What is Routing?
[ApiController] [Route("api/products")] public class ProductController : ControllerBase { [HttpGet("{id}")] public IActionResult GetProduct(int id) { return Ok(); } }
- Controller → ProductController
- Action → GetProduct
- id → 10
Q18. What are the different types of Routing?
- Conventional routing
- Attribute routing
{controller}/{action}/{id?}, and ASP.NET Core uses that convention to map URLs to controller actions. It is commonly associated with MVC applications, while Web APIs often prefer attribute routing.var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); var app = builder.Build(); app.UseRouting(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
public class ProductController : Controller { public IActionResult Index() { return Ok("All Products"); } public IActionResult Details(int id) { return Ok($"Product {id}"); } }
[ApiController] [Route("api/products")] public class ProductController : ControllerBase { [HttpGet] public IActionResult GetProducts() { return Ok("All Products"); } [HttpGet("{id}")] public IActionResult GetProduct(int id) { return Ok($"Product {id}"); } [HttpPost] public IActionResult CreateProduct() { return Ok("Product Created"); } }
Conventional Vs Attribute Routing.
| Conventional Routing | Attribute Routing |
|---|---|
| Route defined centrally | Route defined on controller/action |
| It is based on conventions | It is explicit |
| Common in MVC applications | Very common in Web APIs |
| Less configuration on controllers | More explicit controller configuration |
| URL often follows method/controller names | URL can be completely different from the method name |
Q19. What is the purpose of the wwwroot folder?
The wwwroot folder is a special folder in an ASP.NET Core web application that serves as the web root. Its purpose is to store static files, such as HTML, CSS, JavaScript, images, and other client-side assets that need to be directly accessible by the web browser.
When a web application receives a request, the web server looks for the requested resource within the wwwroot folder. If the resource is found in this folder, the web server serves it directly to the client without involving the ASP.NET Core middleware pipeline.
If we want to change the path of the wwwroot folder, then you need to set the path of the wwwroot folder in the WebRootPath property of the WebApplicationOptions class.
var builder = WebApplication.CreateBuilder(new WebApplicationOptions() { WebRootPath = "foldername" });
UseStaticFiles() enables ASP.NET Core to serve files from wwwroot.Q20. What is Controller?
[ApiController] [Route("api/products")] public class ProductsController : ControllerBase { [HttpGet("{id}")] public IActionResult GetProduct(int id) { return Ok(new { Id = id, Name = "Laptop" }); } }
- Receives the HTTP request
- Gets input from route/query/body
- Calls application/business services
- Returns an HTTP response such as 200, 201, 400, 404, or 500
- ControllerBase → Commonly used for Web APIs
- Controller → Extends ControllerBase and adds MVC/View-related functionality
Q21. What is an Action Method?
[ApiController] [Route("api/products")] public class ProductsController : ControllerBase { [HttpGet("{id}")] public IActionResult GetProduct(int id) { return Ok($"Product: {id}"); } [HttpGet("{id}")] public ActionResult<Product> GetProduct(int id) { var product = GetProductFromDb(id); if (product == null) return NotFound(); return Ok(product); } }
Q22. Explain different types of Action Results in ASP.NET Core?
| Action Result | HTTP Status | Purpose | Common Usage |
|---|---|---|---|
Ok() / Ok(object) |
200 | Request completed successfully | GET requests returning data |
Created() |
201 | New resource was successfully created | POST requests |
CreatedAtAction() |
201 | Creates a resource and provides the URL of the created resource | RESTful POST requests |
NoContent() |
204 | Request succeeded but there is no response body | PUT, PATCH, DELETE |
BadRequest() |
400 | Client sent an invalid request | Invalid input, validation errors |
Unauthorized() |
401 | Authentication is required or credentials are invalid | Missing/invalid access token |
Forbid() |
403 | User is authenticated but not authorized | Insufficient permissions/roles |
NotFound() |
404 | Requested resource does not exist | Resource lookup by ID |
Conflict() |
409 | Request conflicts with the current state of the resource | Duplicate record, concurrency conflict |
UnprocessableEntity() |
422 | Request is syntactically valid but cannot be processed semantically | Business validation failures |
Redirect() |
3xx | Redirects the client to another URL | URL redirection |
RedirectToAction() |
3xx | Redirects to another controller action | MVC applications |
File() |
200 | Returns a file to the client | PDF, image, Excel, download APIs |
Content() |
200 | Returns custom text/content | Plain text, custom content |
Json() |
200 | Returns data formatted as JSON | MVC/custom JSON responses |
View() |
200 | Returns an MVC Razor view | ASP.NET Core MVC applications |
Q23. What’s the HttpContext object? How can you access it within a Controller?
HttpContext is an object in ASP.NET Core that represents the current HTTP request and response context. It provides access to information about the client request, HTTP response, user identity, headers, cookies, session, request services, and other information related to the current request.public class ProductsController : ControllerBase { [HttpGet] public IActionResult Get() { var userAgent = HttpContext.Request.Headers.UserAgent; var user = HttpContext.User; return Ok(); } }
IHttpContextAccessor when you need HttpContext outside a Controller, such as in a service:public class ProductService { private readonly IHttpContextAccessor _httpContextAccessor; public ProductService(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public string GetUserName() { return _httpContextAccessor.HttpContext?.User?.Identity?.Name; } }
HttpContext is already available through the base Controller/ControllerBase class. IHttpContextAccessor is mainly used when you need access to the current HTTP context from a class that is outside the controller, such as a service.Q24. What is model binding in ASP.NET CORE?
Model Binding in ASP.NET Core is the process of automatically taking data from an HTTP request and converting it into .NET objects or parameters that can be used by a controller action. It saves us from manually reading values from the request, converting strings to integers, parsing JSON, etc.public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; } }
[ApiController] [Route("api/products")] public class ProductsController : ControllerBase { [HttpPost] public IActionResult CreateProduct(Product product) { return Ok(product); } }
POST /api/products Content-Type: application/json { "id": 101, "name": "Laptop", "price": 75000, "category": "Electronics" }
HTTP Request Body ↓ Model Binding ↓ Product object ├── Id = 101 ├── Name = "Laptop" ├── Price = 75000 └── Category = "Electronics" ↓ CreateProduct(Product product)
Q25. How validation works in ASP.NET CORE MVC and how they follow DRY principle?
public class Product { [Required] [StringLength(100)] public string Name { get; set; } [Range(1, 100000)] public decimal Price { get; set; } }
[HttpPost] public IActionResult Create(Product product) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // Save product return Ok(product); }
Note: With [ApiController], ASP.NET Core automatically performs model-state validation and can return a 400 Bad Request response when validation fails, so you often don't need to explicitly write: if (!ModelState.IsValid)Q26. How to create Custom Validation?
Custom validation in ASP.NET Core is used when built-in Data Annotation attributes such as [Required], [Range], or [StringLength] cannot express a business rule. We can create custom validation using ValidationAttribute, IValidatableObject, or custom model-validation mechanisms.
Example: Employee age must be 18 or above.
using System.ComponentModel.DataAnnotations; public class MinimumAgeAttribute : ValidationAttribute { private readonly int _minimumAge; public MinimumAgeAttribute(int minimumAge) { _minimumAge = minimumAge; } protected override ValidationResult? IsValid( object? value, ValidationContext validationContext) { if (value == null) return ValidationResult.Success; int age = Convert.ToInt32(value); if (age < _minimumAge) { return new ValidationResult( $"{validationContext.DisplayName} must be at least {_minimumAge} years old."); } return ValidationResult.Success; } }
public class Employee { [Required] public string Name { get; set; } [MinimumAge(18)] public int Age { get; set; } }
{ "errors": { "Age": [ "Age must be at least 18 years old." ] } }
Q27. What is the MVC pattern?
- Model: The Model represents application data and business rules.
- View: The View is responsible for presenting data to the user. In ASP.NET Core MVC, this is typically a Razor View (.cshtml) that generates HTML.
- Controller: The Controller receives the HTTP request, coordinates with services/models, and decides what response should be returned.
![]() |
| ASP.NET Core MVC Flow |
- Clean separation of concerns.
- Each component (model, view, and controller) performs a single responsibility.
- Identifying and fixing errors will be easy.
- Each component can be developed independently.
- The view and controller depend on the model, but the model doesn't depend on either the view or the controller.
- Unit testing of individual components is easier.
Note: For an ASP.NET Core Web API, you usually don't have a View. So when discussing MVC in an interview, distinguish between ASP.NET Core MVC applications and ASP>NET Core Web APIs.
Q28. Explain the differences between ViewData and ViewBag.
Both ViewData and ViewBag are used to pass small amounts of data from the Controller to a View in ASP.NET Core MVC. The main difference is how they access the data. ViewData uses a dictionary with string keys to access the data, while ViewBag uses property names.
Important point: ViewBag and ViewData actually share the same underlying storage.
ViewData Example:
public IActionResult Index() { ViewData["Message"] = "Hello World"; return View(); }
public IActionResult Index() { ViewBag.Message = "Hello World"; return View(); }
Q29. Explain strongly-typed views.
A strongly-typed view is a Razor view associated with a specific model type using @model. It provides compile-time type checking, IntelliSense, and a clear contract between the Controller and View, making it safer and more maintainable than ViewBag or ViewData.
public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }public IActionResult Details(int id) { var product = new Product { Id = 101, Name = "Laptop", Price = 75000 }; return View(product); }
@model Product <h2>@Model.Name</h2> <p>Price: @Model.Price</p> <p>Product ID: @Model.Id</p>
@model directive defines the type of model the View expects, while @Model provides access to the actual model instance passed by the Controller.Q30. Explain the purpose and usage of layout views in ASP.NET Core?
@RenderBody() and can provide additional content through @RenderSection(). This promotes reuse and follows the DRY principle.<!DOCTYPE html> <html> <head> <title>My Application</title> <link rel="stylesheet" href="~/css/site.css" /> </head> <body> <header> <h1>My Application</h1> <nav> <a href="/">Home</a> <a href="/Products">Products</a> </nav> </header> <main> @RenderBody() </main> <footer> <p>© 2026 My Application</p> </footer> </body> </html>
Q31. Explain partial views in ASP.NET Core.
Q32. Explain the difference between PartialAsync() and RenderPartialAsync().
PartialAsync() and RenderPartialAsync() are asynchronous HTML helper methods used to render partial views in ASP.NET Core MVC. The main difference is that PartialAsync() returns the rendered HTML as IHtmlContent, whereas RenderPartialAsync() writes the rendered HTML directly to the output.@model Product <h2>Product Details</h2> @await Html.PartialAsync("_Product", Model)
- PartialAsync() renders _Product.cshtml.
- It returns the generated HTML as IHtmlContent.
- Razor writes that HTML into the page.
@model Product <h2>Product Details</h2> @{ await Html.RenderPartialAsync("_Product", Model); }
- RenderPartialAsync() renders _Product.cshtml.
- It writes the generated HTML directly to the output.
- It returns Task, not IHtmlContent.
Q33. What are View Components?
using Microsoft.AspNetCore.Mvc; public class CartSummaryViewComponent : ViewComponent { public IViewComponentResult Invoke() { int cartItemCount = 3; return View(cartItemCount); } }
@model int <div class="cart-summary"> Shopping Cart: @Model items </div>
@await Component.InvokeAsync("CartSummary")
| Partial View | View Component |
|---|---|
| Primarily reusable UI markup | Reusable UI with its own presentation logic |
| Receives a model from the caller | Can prepare its own model and retrieve data |
| No dedicated component logic class | Has a dedicated View Component class |
| Suitable for simple UI fragments | Suitable for dynamic, data-driven UI sections |
- A View Component is not a Controller or an HTTP endpoint.
- It supports dependency injection, so you can inject services to retrieve data.
- Its logic is usually defined in an Invoke() or InvokeAsync() method.
- Its Razor view is conventionally stored in Views/Shared/Components/{ComponentName}/Default.cshtml.
Use a View Component over a Partial View when a reusable UI section requires its own presentation logic, data retrieval, or dependency injection. A Partial View is more suitable when I simply need to reuse existing HTML markup and pass a model to it.






