.NET Core
.NET Core
1. What is .NET Core?
Answer:
.NET Core is an open-source, cross-platform framework developed by Microsoft
for building modern, scalable web applications, microservices, APIs, and more.
Unlike the traditional .NET Framework, it supports Windows, Linux, and macOS.
.NET Core provides high performance, flexibility, and a modular system with the
ability to deploy standalone applications.
2. What are the differences between .NET Framework and
.NET Core?
Answer:
- Cross-Platform: .NET
Core is cross-platform (works on Windows, Linux, and macOS), while the
.NET Framework only works on Windows.
- Modularity: .NET
Core is modular and lightweight, while .NET Framework is monolithic.
- Performance: .NET
Core generally provides better performance and scalability.
- Deployment: .NET
Core allows for standalone deployments, whereas .NET Framework relies on
the global installation of the framework.
- Web
Applications: .NET Core is designed to work with modern web
applications like ASP.NET Core, while .NET Framework typically works with
ASP.NET.
3. What is the difference between ASP.NET Core and
ASP.NET MVC?
Answer:
- ASP.NET
Core: It's a unified framework for building web applications,
APIs, microservices, and more. It works on Windows, Linux, and macOS.
ASP.NET Core is the next-generation version of ASP.NET with improvements
in performance, modularity, and flexibility.
- ASP.NET
MVC: It's a framework for building web applications following the
Model-View-Controller architecture, which was part of the older .NET
Framework. It's Windows-only and is less modular compared to ASP.NET Core.
4. What is Dependency Injection in .NET Core?
Answer:
Dependency Injection (DI) is a design pattern used to implement Inversion of
Control (IoC). In .NET Core, DI is used extensively to inject services into
classes rather than creating instances of them manually. It improves
testability, flexibility, and maintains loose coupling. The services are
registered in the Startup.cs file within the ConfigureServices method, and they
are injected into controllers or services via constructor injection.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IEmailService,
EmailService>();
}
5. What is middleware in ASP.NET Core?
Answer:
Middleware is a piece of code that handles requests and responses in the HTTP
pipeline in ASP.NET Core. Each middleware component can either pass the request
to the next middleware or generate a response directly. Common examples of
middleware include authentication, logging, routing, and error handling.
You configure middleware in the Configure method of
Startup.cs:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
6. Explain the role of Program.cs and Startup.cs in a
.NET Core application.
Answer:
- Program.cs: It
contains the entry point of the application, where the web host is created
and configured. It is responsible for starting the application and
configuring services.
- Startup.cs: It
contains the application's configuration, such as registering services in
ConfigureServices and setting up middleware in Configure.
Example of Program.cs:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder
CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
7. What is Entity Framework Core?
Answer:
Entity Framework Core (EF Core) is an Object-Relational Mapping (ORM) framework
for .NET. It allows developers to work with databases using strongly-typed .NET
objects, abstracting away the need for SQL queries. EF Core is lightweight,
cross-platform, and supports various databases such as SQL Server, SQLite,
MySQL, and PostgreSQL.
You define models in C# code, and EF Core automatically
generates the database schema.
8. What is the difference between IEnumerable<T>
and IQueryable<T>?
Answer:
- IEnumerable<T>: It
is used for in-memory collections and is part of System.Linq. It executes
LINQ queries on the client side (in-memory).
- IQueryable<T>: It
is used for querying data from a data source such as a database and is
part of System.Linq. It translates LINQ queries into the appropriate
database query language (SQL). Queries are executed on the database
server, which improves performance for large data sets.
9. What is the purpose of async and await in C#?
Answer:
async and await are used to make asynchronous programming easier in C#. An
async method allows asynchronous execution and returns a Task or Task<T>.
The await keyword is used to pause the execution of a method until the awaited
task completes.
Example:
public async Task<IActionResult> GetDataAsync()
{
var data = await
_service.GetDataFromDatabaseAsync();
return Ok(data);
}
10. What are the new features introduced in C# 9 or C#
10?
Answer (C# 9):
- Records: Immutable
reference types with value-based equality.
- Init-only
Properties: Properties that can only be set during object
initialization.
- Pattern
Matching Enhancements: New pattern matching features like is not
null and relational patterns.
- Top-level
Statements: The ability to write programs without needing a Main
method.
Answer (C# 10):
- Global
Usings: Allowing to define usings globally in the project.
- File-Scoped
Namespace Declaration: A more concise way to declare namespaces.
- Lambda
Expression Improvements: Improved type inference for lambda
expressions.
11. Explain the concept of Garbage Collection in .NET
Core.
Answer:
Garbage Collection (GC) in .NET Core is an automatic memory management system
that reclaims memory by collecting and disposing of objects that are no longer
in use. The .NET runtime uses a generational GC system that organizes objects
into three generations (0, 1, and 2) based on their lifetimes. Objects in Gen 0
are collected more frequently than those in Gen 2. The garbage collector runs
in the background and helps to prevent memory leaks and optimize performance.
12. What is the difference between Task and Thread in C#?
Answer:
- Thread: A
thread represents an independent unit of execution in a process. Threads
can be used to perform multiple operations concurrently, but they are
relatively heavier and can lead to performance issues if not managed
properly.
- Task: A
task represents an asynchronous operation and is lighter than a thread. It
is typically used to represent an operation that will eventually complete.
Tasks use threads from the thread pool, which improves performance in
asynchronous programming.
13. What is a NuGet package in .NET Core?
Answer:
NuGet is the package manager for .NET, and NuGet packages are precompiled
libraries or tools that can be used to extend .NET applications. These packages
can be easily added to a project via the NuGet Package Manager or through the
command line. They provide functionality like logging, authentication, or any
other reusable component.
14. What is the purpose of the ConfigureServices method
in Startup.cs?
Answer:
The ConfigureServices method is used to register services (such as
repositories, logging, and other dependencies) that the application will need
during runtime. It is called by the runtime to configure services for
dependency injection.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IProductService,
ProductService>();
}
15. What is the difference between AddScoped,
AddSingleton, and AddTransient in Dependency Injection?
Answer:
- AddScoped: Registers
the service with a scope. A new instance of the service is created for
each HTTP request (in web applications) or per scope. It is typically used
for services that are tied to a specific request lifecycle.
- AddSingleton: Registers
the service as a singleton. Only one instance of the service is created
for the entire application's lifetime. It is shared across all requests
and components.
- AddTransient: Registers
the service as transient. A new instance of the service is created every
time it is requested.
Example:
services.AddScoped<IMyService, MyService>(); // Scoped
(per request)
services.AddSingleton<IMyService, MyService>(); //
Singleton (one instance)
services.AddTransient<IMyService, MyService>(); //
Transient (new instance each time)
16. What is the difference between synchronous and
asynchronous methods in C#?
Answer:
- Synchronous
Methods: In a synchronous method, the program waits for the
current operation to complete before moving on to the next one. If one
operation takes a long time, it blocks the entire thread.
- Asynchronous
Methods: An asynchronous method allows other operations to run
while it waits for a time-consuming task to finish. It improves
application responsiveness and is generally used in I/O-bound operations
like web requests or database queries.
Example of asynchronous method:
public async Task<string> GetDataAsync()
{
var data = await
httpClient.GetStringAsync("https://example.com");
return data;
}
17. What is the role of Configure method in Startup.cs?
Answer:
The Configure method is where the HTTP request pipeline is set up in an ASP.NET
Core application. Middleware components are added to the pipeline in this
method, and they define the order in which the requests are handled. The
pipeline is responsible for processing HTTP requests, handling errors,
authentication, authorization, routing, and more.
Example:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
18. Explain the difference between POST and PUT HTTP
methods in RESTful APIs.
Answer:
- POST: Used
to create a new resource. It is generally used when submitting data to be
processed by the server (e.g., creating a new record in the database). It
is not idempotent, meaning repeated POST requests may result in multiple
resource creations.
- PUT: Used
to update an existing resource or create a new one if the resource does
not already exist. It is idempotent, meaning multiple PUT requests with
the same data should result in the same resource state.
Example:
// POST - Create a new resource
[HttpPost]
public IActionResult Create([FromBody] Product product)
{
_context.Products.Add(product);
_context.SaveChanges();
return CreatedAtAction(nameof(Get), new {
id = product.Id }, product);
}
// PUT - Update an existing resource
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody] Product
product)
{
if (id != product.Id)
{
return
BadRequest();
}
_context.Entry(product).State =
EntityState.Modified;
_context.SaveChanges();
return NoContent();
}
19. What is the difference between ViewData, ViewBag, and
TempData in MVC?
Answer:
- ViewData: A
dictionary object (ViewDataDictionary) that is used to pass data from the
controller to the view. It is available only during the current request.
- ViewBag: A
dynamic object that is a wrapper around ViewData. It provides a more
concise way to pass data to views without needing to access the
dictionary.
- TempData: Used
to store data that is needed only for the next request. It persists across
redirects, making it useful for passing data between controller actions.
Example:
// ViewData
ViewData["Message"] = "Hello,
ViewData!";
// ViewBag
ViewBag.Message = "Hello, ViewBag!";
// TempData
TempData["Message"] = "Hello,
TempData!";
20. What is Caching, and how is it implemented in ASP.NET
Core?
Answer:
Caching is the process of storing data in a temporary storage to reduce the
time and resources spent fetching the same data repeatedly. In ASP.NET Core,
caching can be implemented in various ways:
- In-Memory
Caching: Stores data in the memory of the server.
- Distributed
Caching: Stores data in a central cache like Redis, making it
accessible across multiple servers.
- Response
Caching: Caches entire HTTP responses to avoid regenerating the
same content for every request.
Example of in-memory caching:
public class HomeController : Controller
{
private readonly ICacheService
_cacheService;
public HomeController(ICacheService
cacheService)
{
_cacheService =
cacheService;
}
public IActionResult Index()
{
var data =
_cacheService.GetOrAdd("key", () => GetDataFromDatabase());
return
View(data);
}
}
21. What is the significance of async in LINQ queries?
Answer:
LINQ queries in .NET are usually executed synchronously, but for I/O-bound
operations (like fetching data from a database), you can use asynchronous LINQ
methods. Asynchronous LINQ (e.g., ToListAsync, FirstOrDefaultAsync) allows for
non-blocking execution, improving the responsiveness of applications.
Example of asynchronous LINQ:
var products = await _context.Products.Where(p => p.Price
> 100).ToListAsync();
22. What is a CancellationToken, and how is it used?
Answer:
A CancellationToken is used to propagate a cancellation request through
asynchronous operations. It allows you to cancel a long-running task, such as
database queries or HTTP requests, before completion. You can pass a
CancellationToken to tasks or methods that support cancellation.
Example:
public async Task<IActionResult>
GetData(CancellationToken cancellationToken)
{
var data = await
_dataService.GetDataAsync(cancellationToken);
return Ok(data);
}
Cancel the operation:
var cts = new CancellationTokenSource();
cts.Cancel(); // Will cancel the operation
23. What is the purpose of appsettings.json in an ASP.NET
Core application?
Answer:
appsettings.json is a configuration file used in ASP.NET Core to store
application settings like connection strings, API keys, and other configuration
values. The settings are loaded during the application's startup and can be
accessed via the IConfiguration interface.
Example of appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection":
"Server=myserver;Database=mydb;Trusted_Connection=True;"
},
"AppSettings": {
"ApiKey":
"my-api-key"
}
}
Accessing the settings in the application:
public class MyService
{
private readonly IConfiguration
_configuration;
public MyService(IConfiguration
configuration)
{
_configuration =
configuration;
}
public string GetConnectionString()
{
return
_configuration.GetConnectionString("DefaultConnection");
}
}
24. What are ValueTuple and its advantages over regular
Tuple?
Answer:
A ValueTuple is a lightweight, value-type tuple introduced in C# 7.0. It has
better performance and offers named elements, making it more convenient to work
with compared to the older Tuple. ValueTuple is also more memory efficient
because it avoids heap allocation.
Example:
var result = (Name: "John", Age: 30);
Console.WriteLine(result.Name); // Output: John
25. What is the role of ConfigureServices method in
Startup.cs and how does dependency injection work in ASP.NET Core?
Answer:
- ConfigureServices
method: This method is used to configure services in the
Dependency Injection (DI) container. It's where you register services,
middleware, and dependencies that the application will need during its
lifecycle. Services are added to the DI container using methods like
AddSingleton, AddScoped, or AddTransient, depending on the desired
lifetime of the service.
- Dependency
Injection in ASP.NET Core: ASP.NET Core has a built-in DI
framework that manages the lifecycle of objects and their dependencies. It
automatically injects dependencies (such as services, repositories, etc.)
into constructors of controllers, services, or other components that need
them.
Example:
public void ConfigureServices(IServiceCollection services)
{
// Registering a service with Scoped
lifetime
services.AddScoped<IProductService,
ProductService>();
// Registering a singleton service
services.AddSingleton<IDatabaseConnection, DatabaseConnection>();
// Registering a transient service
services.AddTransient<IEmailSender,
EmailSender>();
}
26. What are Action Filters and how do they work in
ASP.NET Core?
Answer:
Action filters in ASP.NET Core are used to run custom code before or after an
action method executes. They allow you to perform tasks like logging,
validation, or caching at the action level or globally across the application.
Action filters can be used for cross-cutting concerns like security or data
validation.
There are several types of action filters:
- OnActionExecuting:
Runs before the action method is called.
- OnActionExecuted:
Runs after the action method is executed.
Example:
public class MyActionFilter : IActionFilter
{
public void
OnActionExecuting(ActionExecutingContext context)
{
// Logic before
action execution
}
public void
OnActionExecuted(ActionExecutedContext context)
{
// Logic after
action execution
}
}
// Registering filter globally
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options
=>
{
options.Filters.Add(new MyActionFilter());
});
}
27. What is the IOptions<T> interface in .NET Core
and when should you use it?
Answer:
IOptions<T> is used to access configuration data in a strongly-typed
manner. It's useful for binding settings from appsettings.json (or other
configuration sources) to a C# class. IOptions<T> provides a way to
access configuration options in a safe and centralized manner.
- IOptions<T>:
For reading configuration values at the time of request.
- IOptionsSnapshot<T>:
For reading options that change during the application's lifecycle (only
in scoped services).
- IOptionsMonitor<T>:
For reading options that can be changed at runtime and provides change
tracking.
Example:
// appsettings.json
{
"AppSettings": {
"ApiKey": "some-api-key"
}
}
// Configuration model
public class AppSettings
{
public string ApiKey { get; set; }
}
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}
// Using IOptions in a class
public class MyService
{
private readonly AppSettings
_appSettings;
public
MyService(IOptions<AppSettings> options)
{
_appSettings =
options.Value;
}
public string GetApiKey()
{
return
_appSettings.ApiKey;
}
}
28. What are some best practices for handling exceptions
in an ASP.NET Core application?
Answer:
Handling exceptions in an ASP.NET Core application is important for maintaining
security and user experience. Below are some best practices:
- Use
Global Error Handling: Use UseExceptionHandler middleware in the
Configure method to catch unhandled exceptions globally.
- Log
Exceptions: Always log exceptions to help with debugging and
improving your system.
- Return
Appropriate HTTP Status Codes: Return status codes like 400 (Bad
Request) or 500 (Internal Server Error) based on the exception type.
- Custom
Error Pages: Customize error pages for common exceptions like 404
(Not Found) or 500 (Server Error).
Example:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
}
// Error action in controller
public IActionResult Error()
{
return View(); // Custom error page view
}
Logging Example:
public class MyService
{
private readonly ILogger<MyService>
_logger;
public MyService(ILogger<MyService>
logger)
{
_logger = logger;
}
public void SomeMethod()
{
try
{
// Code that may throw an exception
}
catch (Exception
ex)
{
_logger.LogError(ex, "An error occurred while processing the
request.");
throw; // Rethrow the exception if necessary
}
}
}
29. What is the async-await pattern in C#, and how does
it work?
Answer:
The async and await keywords are used to define asynchronous methods in C#. The
async keyword is applied to a method to indicate that it will contain
asynchronous code, and the await keyword is used inside the method to pause its
execution until the awaited task is complete.
- async
method: Marks the method as asynchronous and typically returns
Task or Task<T>.
- await
expression: Pauses the method execution until the awaited Task
completes.
Example:
public async Task<IActionResult> GetData()
{
var data = await
_service.GetDataFromDatabaseAsync();
return Ok(data);
}
30. Explain the HttpClient class and how it is used in
.NET Core.
Answer:
The HttpClient class in .NET Core is used to send HTTP requests and receive
HTTP responses. It is an essential class for consuming RESTful APIs and web
services.
- Best
practice: HttpClient should be used as a singleton to avoid
socket exhaustion due to its internal connection management.
- You
can use HttpClientFactory in .NET Core to create HttpClient instances
efficiently.
Example using HttpClient:
public class MyService
{
private readonly HttpClient _httpClient;
public MyService(HttpClient httpClient)
{
_httpClient =
httpClient;
}
public async Task<string>
GetDataAsync()
{
var response =
await _httpClient.GetStringAsync("https://api.example.com/data");
return response;
}
}
// Registering HttpClient in DI container
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<MyService>();
}
31. What is the difference between Task.Run() and
Task.Factory.StartNew()?
Answer:
- Task.Run() is
the recommended method for creating a task in modern applications. It
queues the task to run on the ThreadPool and is typically used for running
a piece of work asynchronously.
- Task.Factory.StartNew() provides
more advanced options for controlling the execution of the task, such as
specifying scheduling options, task creation options, and more. It's more
flexible but not as commonly used in basic scenarios.
Example of Task.Run:
public async Task RunTaskAsync()
{
await Task.Run(() =>
{
// Long-running
task
});
}
Example of Task.Factory.StartNew:
public void RunTask()
{
Task.Factory.StartNew(() =>
{
// Long-running
task
}, CancellationToken.None,
TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
32. What are Concurrency and Parallelism, and how are
they different in .NET Core?
Answer:
- Concurrency refers
to managing multiple tasks at once, but not necessarily executing them
simultaneously. It allows for tasks to make progress by switching between
them as needed (e.g., by using asynchronous programming).
- Parallelism refers
to executing multiple tasks simultaneously, often on different processors
or cores. It is typically used for CPU-bound tasks.
Example of Concurrency:
public async Task ConcurrencyExample()
{
var task1 = Task.Run(() =>
SomeLongRunningOperation());
var task2 = Task.Run(() =>
AnotherLongRunningOperation());
await Task.WhenAll(task1, task2);
// Run tasks concurrently
}
Example of Parallelism:
public void ParallelExample()
{
Parallel.For(0, 100, i =>
{
// Perform
CPU-bound operation in parallel
});
}
33. What is the purpose of the UseEndpoints method in the
Configure method of Startup.cs?
Answer: The UseEndpoints method in the Configure
method of Startup.cs is used to define the endpoints (routes) that the
application will respond to. It maps the endpoints to controllers, Razor Pages,
or other routing handlers. This method should be called after middleware like
UseRouting to ensure that the application knows how to route incoming requests.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseRouting(); // Enable routing
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
34. What is the difference between IEnumerable<T>,
IQueryable<T>, and List<T> in C#?
Answer:
- IEnumerable<T>:
Represents a collection of objects that can be iterated over, but it is
evaluated in memory (i.e., not lazy-loaded). It is a common interface used
in LINQ to operate on in-memory collections.
- IQueryable<T>:
Represents a collection that can be queried, typically with deferred
execution. It is most commonly used with Entity Framework to query a
database and supports translating LINQ queries into SQL. IQueryable allows
for building queries that are executed at a later time (on the database).
- List<T>:
A concrete class that implements IEnumerable<T> and
ICollection<T>. It stores a collection of objects in memory, and
operations on List<T> are executed eagerly (immediately).
Example of IQueryable vs. IEnumerable:
var query = dbContext.Products.Where(p => p.Price >
100); // IQueryable
var result = query.ToList(); // Executes the query and
returns a List<T>
35. What is a Middleware in ASP.NET Core and how does it
work?
Answer: Middleware is a piece of code that sits
in the HTTP request-response pipeline. It can inspect, modify, or short-circuit
the HTTP request or response. ASP.NET Core uses middleware to handle concerns
like logging, authentication, exception handling, and more.
Middleware is configured in the Configure method of the
Startup.cs file using the IApplicationBuilder interface.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<MyCustomMiddleware>(); // Custom middleware
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate
next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext
context)
{
// Custom logic
before calling next middleware
await
_next(context);
// Custom logic
after calling next middleware
}
}
36. What is Dependency Injection and why is it important
in ASP.NET Core?
Answer: Dependency Injection (DI) is a design
pattern used to implement IoC (Inversion of Control). It allows the automatic
injection of dependencies (services) into classes that need them, thus
decoupling the components of an application and improving testability and
maintainability.
In ASP.NET Core, DI is built into the framework, and you
register services in the ConfigureServices method of Startup.cs. The DI
container automatically resolves these dependencies when needed.
Example of Dependency Injection:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IProductService,
ProductService>();
}
public class HomeController : Controller
{
private readonly IProductService
_productService;
public HomeController(IProductService
productService)
{
_productService =
productService;
}
public IActionResult Index()
{
var products =
_productService.GetProducts();
return
View(products);
}
}
37. What is the difference between HttpContext and
HttpRequest in ASP.NET Core?
Answer:
- HttpContext:
Represents the entire context of an HTTP request and response. It contains
all the details of the request, response, session, user, and other
components involved in handling the request.
- HttpRequest:
A property of HttpContext, it specifically represents the request data
sent by the client. It contains the request's URL, headers, query strings,
body, and other request-specific details.
Example:
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
var url =
context.Request.Path; // HttpRequest
var method =
context.Request.Method;
await next();
});
}
38. What are the differences between ASP.NET Core and
ASP.NET MVC?
Answer:
- ASP.NET
Core: A cross-platform, high-performance web framework that allows you
to build web applications, APIs, and more. It is lightweight and modular,
making it easier to configure and maintain.
- ASP.NET
MVC: A web application framework built on top of the .NET Framework
(older version) and used mainly for building web applications that follow
the Model-View-Controller pattern. It runs only on Windows.
Key differences:
- ASP.NET
Core is cross-platform, while ASP.NET MVC is Windows-specific.
- ASP.NET
Core is more modular and can be customized to include only the required
features.
- ASP.NET
Core uses the new Kestrel web server, whereas ASP.NET MVC uses IIS.
Example of ASP.NET Core controller:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
39. What is IActionResult in ASP.NET Core MVC, and how
does it differ from ActionResult?
Answer:
- IActionResult:
An interface that represents the result of an action method in ASP.NET
Core. It defines a contract for all types of action results returned by
controller methods.
- ActionResult:
A concrete class that implements IActionResult. It is a base class for
many common action result types like ViewResult, JsonResult,
RedirectResult, etc.
You can use IActionResult as the return type for flexibility
in returning different types of results.
Example:
public IActionResult Index()
{
return View();
}
public IActionResult RedirectToHome()
{
return
RedirectToAction("Index");
}
40. What is Entity Framework Core and how is it different
from Entity Framework?
Answer: Entity Framework Core (EF Core) is a
lightweight, cross-platform version of Entity Framework. It is used for
Object-Relational Mapping (ORM), allowing developers to work with databases
using C# objects rather than SQL queries.
Key differences:
- Cross-platform:
EF Core is designed to work on multiple platforms, while Entity Framework
(EF 6.x) is only available for Windows.
- Performance:
EF Core is optimized for better performance and scalability.
- Features:
EF Core introduces new features such as better LINQ support, a more
modular design, and support for NoSQL databases (like Cosmos DB).
Example of EF Core:
public class ApplicationDbContext : DbContext
{
public DbSet<Product> Products {
get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
41. What is the role of IConfiguration in an ASP.NET Core
application?
Answer: IConfiguration is an interface that
provides a way to access configuration settings in ASP.NET Core. It allows you
to retrieve settings from different sources like appsettings.json, environment
variables, or Azure Key Vault.
- It’s
typically injected into classes (like controllers or services) to read
configuration values.
- It
is set up and configured in the Startup.cs file using IConfiguration and
is often bound to strongly-typed objects.
Example:
public class MyService
{
private readonly IConfiguration
_configuration;
public MyService(IConfiguration
configuration)
{
_configuration =
configuration;
}
public string GetConnectionString()
{
return
_configuration.GetConnectionString("DefaultConnection");
}
}
42. What is the significance of IWebHostEnvironment in
ASP.NET Core?
Answer: IWebHostEnvironment provides information
about the web hosting environment the application is running in (e.g.,
Development, Staging, Production). It helps to tailor configuration and
behavior depending on the environment.
Example:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
}
43. What is Kestrel in ASP.NET Core?
Answer: Kestrel is a cross-platform web server
used by ASP.NET Core applications. It is lightweight, high-performance, and
designed to handle HTTP requests directly. Kestrel is often used as the default
web server, but in production environments, it is typically paired with a
reverse proxy server like Nginx or IIS.
Why use Kestrel?
- It's
built for performance and scalability.
- It
is cross-platform, making ASP.NET Core applications portable across
Windows, Linux, and macOS.
- It
is highly customizable and can be configured for different types of
requests.
Example:
public static IHostBuilder CreateHostBuilder(string[] args)
=>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>().UseKestrel();
});
44. What are Razor Pages in ASP.NET Core?
Answer: Razor Pages is a feature in ASP.NET Core
that provides a simpler way to build web applications using the MVC
(Model-View-Controller) pattern but without the need for controllers. It’s
designed for page-focused scenarios, where each page corresponds to a
particular function (e.g., Create, Edit, Delete).
Razor Pages are organized by pages (views) rather than
controllers, and they help developers build simpler applications quickly.
Example:
public class IndexModel : PageModel
{
private readonly
ILogger<IndexModel> _logger;
public
IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
_logger.LogInformation("Page loaded.");
}
}
Razor page files are typically stored in the Pages folder
with .cshtml extension.
45. What is the Health Checks feature in ASP.NET Core?
Answer: Health Checks in ASP.NET Core are used
to monitor the health of your application, services, or dependencies like
databases, external APIs, etc. Health checks are essential for identifying if
an application is functioning properly or if there are issues requiring
attention.
ASP.NET Core provides built-in middleware to expose health
check endpoints, making it easier to integrate with monitoring systems like
Azure Monitor, Prometheus, or Docker.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
}
public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/health");
}
46. Explain ActionResult<T> in ASP.NET Core.
Answer: ActionResult<T> is a return type
in ASP.NET Core that provides both the HTTP status code and the response body
in a single object. It allows returning various types of HTTP responses while
still returning strongly-typed data.
- ActionResult<T>
is useful in APIs where the action can return various types of responses,
such as 200 OK, 400 BadRequest, or 404 NotFound, but still needs to
include data in the response.
Example:
public ActionResult<Product> GetProduct(int id)
{
var product =
_context.Products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
return
NotFound();
}
return Ok(product); // Returns 200
OK with Product data
}
47. What is the difference between AddSingleton,
AddScoped, and AddTransient in Dependency Injection?
Answer: These methods are used to register
services with different lifetimes in the Dependency Injection (DI) container:
- AddSingleton:
Creates a single instance of the service throughout the application's
lifetime. The instance is created once and shared across all requests.
- AddScoped:
Creates an instance of the service for each request (scoped to the HTTP
request). It is commonly used for services that need to be created and
disposed per request (e.g., database contexts).
- AddTransient:
Creates a new instance of the service every time it is requested. It is
ideal for lightweight, stateless services that don't need to be shared.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILoggingService,
LoggingService>(); // Shared for the lifetime of the app
services.AddScoped<IProductService,
ProductService>(); // New instance per HTTP
request
services.AddTransient<IEmailService,
EmailService>(); // New instance per each use
}
48. What is Authorization in ASP.NET Core, and how does
it work?
Answer: Authorization in ASP.NET Core determines
whether a user has permission to access a resource or perform an action.
Authorization often comes after authentication, which is the process of
verifying who the user is.
ASP.NET Core supports role-based authorization, claims-based
authorization, and policy-based authorization. The Authorize attribute is used
to enforce authorization rules in controllers or action methods.
Example of Role-Based Authorization:
[Authorize(Roles = "Admin")]
public IActionResult AdminDashboard()
{
return View();
}
Example of Policy-Based Authorization:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireRole("Admin"));
});
}
[Authorize(Policy = "AdminOnly")]
public IActionResult AdminPanel()
{
return View();
}
49. What is the UseRouting and UseEndpoints middleware in
ASP.NET Core?
Answer:
- UseRouting:
This middleware is responsible for enabling routing capabilities. It
identifies the URL and matches it to the appropriate controller or Razor
Page based on the route configuration.
- UseEndpoints:
This middleware is responsible for handling the actual execution of the
matched endpoint (i.e., the controller action or Razor Page). It should be
called after UseRouting.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseRouting(); // Enable routing
capabilities
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
50. What are ValueTuple and Tuple in C#? How are they
different?
Answer:
- Tuple:
A Tuple is a data structure that can hold a fixed-size collection of
heterogeneously typed objects. Tuple classes are immutable and can hold
multiple values of different types.
- ValueTuple:
A newer, more lightweight alternative to Tuple that was introduced in C#
7.0. Unlike Tuple, ValueTuple is a value type (struct) and allows for
better performance, especially in terms of memory usage and comparison.
Differences:
- ValueTuple
is more efficient because it is a struct (value type) and doesn't incur
the overhead of a reference type (Tuple is a reference type).
- ValueTuple
supports deconstruction, making it easier to extract values.
Example of ValueTuple:
(int, string) GetTuple()
{
return (1, "Hello");
}
var result = GetTuple();
Console.WriteLine(result.Item1); // 1
Console.WriteLine(result.Item2); // Hello
51. What are Custom Middleware and how do you create one
in ASP.NET Core?
Answer: Custom middleware is middleware that you
write to handle specific application concerns such as logging, validation,
custom exception handling, etc.
To create custom middleware:
- Define
a class that implements the IMiddleware interface or simply use a delegate
that accepts HttpContext.
- Register
your custom middleware in the Configure method of Startup.cs.
Example of Custom Middleware:
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate
next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext
context)
{
// Custom logic
before the request is processed
await
_next(context); // Continue processing the request
// Custom logic
after the request is processed
}
}
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<MyCustomMiddleware>(); // Registering custom
middleware
}
52. Explain ActionResult with different HTTP status
codes.
Answer: ActionResult is a base class that helps
in returning various HTTP status codes with the response body.
Commonly used ActionResult types:
- Ok():
Returns HTTP status code 200 (OK).
- Created():
Returns HTTP status code 201 (Created).
- BadRequest():
Returns HTTP status code 400 (Bad Request).
- NotFound():
Returns HTTP status code 404 (Not Found).
- Unauthorized():
Returns HTTP status code 401 (Unauthorized).
- InternalServerError():
Returns HTTP status code 500 (Internal Server Error).
Example:
public ActionResult<Product> GetProduct(int id)
{
var product =
_productService.GetProduct(id);
if (product == null)
{
return
NotFound();
}
return Ok(product);
}
53. What is the role of ConfigureServices and Configure
methods in Startup.cs?
Answer:
- ConfigureServices:
This method is used for configuring services that the application will
use. It is called during application startup and is primarily used for
dependency injection (DI) configuration. You register services here using
IServiceCollection (e.g., database contexts, identity services,
authentication schemes, etc.).
- Configure:
This method is used to set up the HTTP request pipeline. It is where you
configure middleware components that handle requests and responses (e.g.,
authentication, logging, MVC routing, etc.). It is called after
ConfigureServices.
Example:
public void ConfigureServices(IServiceCollection services)
{
// Register services for dependency
injection
services.AddMvc();
}
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
54. What is the difference between IActionResult and
ActionResult<T> in ASP.NET Core?
Answer:
- IActionResult:
It is the base interface for action results. It represents a generic
result from an action method. It can return different types of responses
such as ViewResult, JsonResult, RedirectResult, etc.
- ActionResult<T>:
It is a concrete class that inherits from IActionResult and is typically
used when working with APIs. It allows returning a strongly-typed response
(e.g., a Product object) along with the HTTP status code in the response.
It is useful for APIs where you want to return both data and HTTP status
codes.
Example:
// IActionResult example
public IActionResult Get()
{
return Ok(new { Name = "Test"
});
}
// ActionResult<T> example
public ActionResult<Product> GetProduct(int id)
{
var product =
_dbContext.Products.FirstOrDefault(p => p.Id == id);
if (product == null) return NotFound();
return Ok(product); // Returns 200 OK
with product data
}
55. Explain AsNoTracking in Entity Framework Core.
Answer: AsNoTracking is a method in Entity
Framework Core that tells the context not to track changes for the returned
entities. This improves performance when reading data because it avoids the
overhead of change tracking.
It is useful for read-only queries or scenarios where you do
not need to modify the retrieved data (e.g., when displaying data in a view).
Example:
public IEnumerable<Product> GetAllProducts()
{
return
_dbContext.Products.AsNoTracking().ToList();
}
56. What are IQueryable and IEnumerable, and how do they
differ in performance?
Answer:
- IQueryable<T>:
Represents a query that can be executed on a remote data source (such as a
database). It supports deferred execution, which means that the query is
not executed until the data is actually accessed. It is commonly used in
LINQ to SQL and LINQ to Entity Framework.
- IEnumerable<T>:
Represents a collection of objects that can be iterated over in memory. It
supports immediate execution, meaning it works with in-memory collections
and executes the query immediately when it is called.
Key Differences:
- IQueryable<T>:
Executes the query on the server, so it is generally used for querying
databases and remote data sources. It allows LINQ queries to be translated
to SQL and run on the database server.
- IEnumerable<T>:
Executes the query in memory, so it is suitable for in-memory collections
(e.g., lists, arrays). It cannot be translated to SQL.
Example:
// IQueryable Example (database query)
var query = dbContext.Products.Where(p => p.Price >
100); // This will not execute until enumerated
// IEnumerable Example (in-memory collection)
var list = products.Where(p => p.Price > 100);
// Executes immediately in memory
57. What is the Scoped lifetime in Dependency Injection
and when should it be used?
Answer: The Scoped lifetime
means that a new instance of the service is created per request (or per
operation). It is typically used for services that should only exist for the
duration of a single request, such as database contexts, unit of work patterns,
or services that maintain a state during the request.
It is useful when you want to ensure that services are
disposed of at the end of the request, typically for things like database
context (DbContext) that require proper cleanup after each request.
Example:
services.AddScoped<IProductService,
ProductService>(); // New instance per HTTP request
58. What is IServiceProvider in ASP.NET Core?
Answer: IServiceProvider is an interface that
represents a service container (DI container) and provides a way to retrieve
services that have been registered in the DI container. It is used to resolve
dependencies manually or at runtime.
It is typically used when services need to be resolved
dynamically, and direct constructor injection is not feasible.
Example:
public class MyController : Controller
{
private readonly IServiceProvider
_serviceProvider;
public MyController(IServiceProvider
serviceProvider)
{
_serviceProvider
= serviceProvider;
}
public IActionResult Index()
{
var
productService = _serviceProvider.GetService<IProductService>();
return
View(productService.GetAllProducts());
}
}
59. What is the purpose of UseMvc vs UseEndpoints in
ASP.NET Core 3.0 and later?
Answer:
- UseMvc:
This was used in ASP.NET Core versions before 3.0 to enable MVC-based
routing and controller mappings. It has been deprecated in favor of
UseEndpoints in ASP.NET Core 3.0 and later.
- UseEndpoints:
This is the new way to configure routing in ASP.NET Core 3.0 and later. It
replaces UseMvc and is part of the new routing system introduced in
ASP.NET Core 3.0, which decouples routing and endpoint resolution from the
middleware pipeline.
Example with UseEndpoints:
public void Configure(IApplicationBuilder app)
{
app.UseRouting(); // Set up routing
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
60. What is the difference between Task.Run() and
Task.Factory.StartNew() in C#?
Answer: Both Task.Run() and
Task.Factory.StartNew() are used to start new tasks asynchronously, but there
are differences in their behavior and intended usage:
- Task.Run():
A simplified method for creating a task that runs on the thread pool. It
is commonly used for background tasks and most simple asynchronous
operations.
- Task.Factory.StartNew():
A more flexible method that provides additional configuration options such
as the ability to specify task creation options, cancellation tokens, and
task schedulers.
Key differences:
- Task.Run()
is easier to use for basic asynchronous operations.
- Task.Factory.StartNew()
provides more control over the creation and execution of tasks (e.g.,
specifying options, scheduling, etc.).
Example:
// Task.Run
Task.Run(() => DoWork());
// Task.Factory.StartNew (more options)
Task.Factory.StartNew(() => DoWork(),
TaskCreationOptions.LongRunning);
61. What is the purpose of IApplicationBuilder.Use in
ASP.NET Core?
Answer: IApplicationBuilder.Use is used to add
middleware components to the HTTP request processing pipeline. Each middleware
can process requests and responses, and optionally call the next middleware in
the pipeline.
Example:
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
// Custom logic
before the request is processed
await next();
// Custom logic
after the request is processed
});
app.UseRouting();
}
62. Explain the role of ConfigureServices in a testable
ASP.NET Core application.
Answer: In a testable ASP.NET Core application,
ConfigureServices is used to set up the dependency injection container, which
makes the application more testable. During testing, you can override or mock
services in ConfigureServices to simulate different behaviors and isolate
components for unit testing.
Example:
public class MyControllerTest
{
private readonly MyController
_controller;
public MyControllerTest()
{
var services =
new ServiceCollection();
services.AddScoped<IProductService, MockProductService>(); // Mocked
service for testing
var provider =
services.BuildServiceProvider();
_controller = new
MyController(provider.GetService<IProductService>());
}
[Fact]
public void TestMethod()
{
var result =
_controller.Get();
Assert.NotNull(result);
}
}
63. What is async and await in C#? How do they work
together?
Answer:
- async:
The async keyword is used to mark a method, lambda, or anonymous method as
asynchronous. This indicates that the method will contain an await
expression and will likely perform asynchronous operations.
- await:
The await keyword is used inside an asynchronous method to indicate where
the method can pause and wait for the completion of an asynchronous
operation. It helps to prevent blocking the main thread while waiting for
long-running operations (e.g., I/O-bound tasks).
When a method is marked as async, it returns a Task or
Task<T>, and the method can use await to wait for other asynchronous
operations to complete. The await keyword can only be used inside methods
marked as async.
Example:
public async Task<int> GetDataAsync()
{
var result = await SomeAsyncOperation();
return result;
}
public async Task SomeAsyncOperation()
{
await Task.Delay(1000); // Simulate a
delay
Console.WriteLine("Operation
completed.");
}
64. What is the HttpClient class in ASP.NET Core?
Answer: HttpClient is a class in the
System.Net.Http namespace that is used to send HTTP requests and receive HTTP
responses from a resource identified by a URI. It is often used to call
external APIs or interact with web services from within ASP.NET Core applications.
When using HttpClient, it is best practice to use it as a
singleton to avoid exhausting system resources (e.g., creating too many
connections). This can be achieved by registering it in ConfigureServices with
dependency injection.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient(); // Register
HttpClient with DI
}
public class MyService
{
private readonly HttpClient _httpClient;
public MyService(HttpClient httpClient)
{
_httpClient =
httpClient;
}
public async Task<string>
GetContentFromApi(string url)
{
var response =
await _httpClient.GetStringAsync(url);
return response;
}
}
65. What is Dependency Injection (DI) in ASP.NET Core,
and how does it work?
Answer: Dependency Injection (DI) is a design
pattern that is used to achieve Inversion of Control (IoC) between classes and
their dependencies. ASP.NET Core has built-in support for DI, allowing objects
to be injected into constructors rather than being manually instantiated. This
promotes loose coupling, easier testing, and better maintainability.
In ASP.NET Core, services are registered in
ConfigureServices and can have different lifetimes: Singleton, Scoped, and
Transient.
Example:
public interface IProductService
{
IEnumerable<Product>
GetAllProducts();
}
public class ProductService : IProductService
{
public IEnumerable<Product>
GetAllProducts()
{
return new
List<Product> { new Product { Name = "Product1" }, new Product
{ Name = "Product2" } };
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IProductService,
ProductService>(); // Register service for DI
}
66. What is the difference between Configure and
ConfigureServices in ASP.NET Core?
Answer:
- ConfigureServices:
This method is used to configure the application's services (e.g.,
authentication, database contexts, MVC services, etc.) and add them to the
Dependency Injection (DI) container.
- Configure:
This method is used to define how the application will handle HTTP
requests through middleware. It is where you configure routing,
authentication, error handling, and any other middleware logic that
processes HTTP requests.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); // Register MVC
services
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Map controller routes
});
}
67. Explain IActionResult and different result types in
ASP.NET Core.
Answer: IActionResult is an interface
representing the result of an action method. It allows returning different
types of results, each corresponding to a different HTTP response type. Common
result types include:
- Ok():
Returns HTTP status code 200 (OK).
- Created():
Returns HTTP status code 201 (Created).
- BadRequest():
Returns HTTP status code 400 (Bad Request).
- NotFound():
Returns HTTP status code 404 (Not Found).
- Unauthorized():
Returns HTTP status code 401 (Unauthorized).
- Redirect():
Returns a redirect HTTP response.
Example:
public IActionResult GetProduct(int id)
{
var product =
_productService.GetProduct(id);
if (product == null)
{
return
NotFound();
}
return Ok(product); // 200 OK with
product data
}
68. What is the UseAuthentication and UseAuthorization
middleware in ASP.NET Core?
Answer:
- UseAuthentication:
This middleware is responsible for authenticating users. It validates the
identity of the user based on the authentication scheme (e.g., cookies,
JWT).
- UseAuthorization:
This middleware is responsible for enforcing authorization policies. After
authentication, it checks if the user has permission to access a resource
or perform an action based on roles, claims, or custom policies.
Both middlewares should be configured in the Configure
method to ensure proper security handling in ASP.NET Core applications.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication(); //
Authenticate users
app.UseAuthorization(); //
Authorize users based on roles or policies
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
69. What is the purpose of UseExceptionHandler in ASP.NET
Core?
Answer: UseExceptionHandler is a middleware used
to handle exceptions globally in an ASP.NET Core application. It allows
developers to define a centralized error-handling mechanism, which can be
configured to return specific error pages or handle errors in a structured way.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseExceptionHandler("/Home/Error"); // Redirects to an
error page
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
In the above example, any unhandled exceptions will be
redirected to the Home/Error action.
70. Explain ActionResult with BadRequest and NotFound.
Answer:
- BadRequest():
Represents an HTTP 400 (Bad Request) response. It is used when the server
cannot process the request due to client-side errors, such as missing
parameters, invalid data, or incorrect input.
- NotFound():
Represents an HTTP 404 (Not Found) response. It is used when the requested
resource (e.g., an item, page, or API endpoint) could not be found.
Example:
public ActionResult<Product> GetProduct(int id)
{
if (id <= 0)
{
return
BadRequest("Invalid product ID.");
}
var product =
_dbContext.Products.Find(id);
if (product == null)
{
return
NotFound("Product not found.");
}
return Ok(product); // Returns 200
OK if product is found
}
71. What are AppSettings.json and IConfiguration in
ASP.NET Core?
Answer: AppSettings.json is a configuration file
used to store application settings (e.g., database connection strings, API
keys, or other configurable parameters) in ASP.NET Core applications. The
IConfiguration interface is used to access and read these configuration
settings.
Example of AppSettings.json:
{
"ConnectionStrings": {
"DefaultConnection":
"Server=myServer;Database=myDb;Trusted_Connection=True;"
},
"AppSettings": {
"ApiKey":
"your-api-key"
}
}
Example of using IConfiguration:
public class MyService
{
private readonly string
_connectionString;
public MyService(IConfiguration
configuration)
{
_connectionString
= configuration.GetConnectionString("DefaultConnection");
}
}
The IConfiguration object allows reading these settings in a
strongly-typed manner.
72. What is the UseRouting and UseEndpoints middleware in
ASP.NET Core?
Answer:
- UseRouting:
This middleware enables routing capabilities by inspecting the incoming
HTTP request and determining which route (endpoint) should be matched.
- UseEndpoints:
This middleware is responsible for defining which actions and controllers
the routes should map to. It should be called after UseRouting.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseRouting(); // Enable routing
capabilities
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
73. What is the difference between IEnumerable and
IQueryable in LINQ?
Answer:
- IEnumerable<T>:
Represents a collection of objects that can be enumerated (iterated). It
works with in-memory collections like lists and arrays, and LINQ queries
executed on IEnumerable<T> are executed in-memory.
- It
uses immediate execution by default, meaning the query
is executed as soon as it is called.
- IQueryable<T>:
Represents a queryable collection, typically used with data sources such
as databases. It allows deferred execution, meaning the query is executed
only when the data is accessed, and it can be translated into a SQL query
when working with an ORM like Entity Framework.
- It
supports deferred execution, which allows the query to be
constructed and optimized before being executed.
Key Difference: IQueryable<T> is suitable for
querying remote data (like databases) and supports query translation (e.g.,
SQL), while IEnumerable<T> is best for in-memory collections.
Example:
// IEnumerable Example (in-memory)
var result1 = products.Where(p => p.Price >
100).ToList();
// IQueryable Example (database query)
var result2 = dbContext.Products.Where(p => p.Price >
100);
74. What is the purpose of UseStaticFiles middleware in
ASP.NET Core?
Answer: UseStaticFiles middleware is used to
serve static files such as HTML, CSS, JavaScript, and images in an ASP.NET Core
application. It is typically used to handle requests for files that do not
require server-side processing.
You can configure it to serve files from the wwwroot folder
or other directories.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // Serves
files from wwwroot folder by default
app.UseRouting();
}
You can also specify a custom path for static files:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new
PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),
"MyFiles")),
RequestPath = "/files"
});
75. What is the role of ConfigureServices in a testable
ASP.NET Core application?
Answer: ConfigureServices is used to register
services in the dependency injection (DI) container in ASP.NET Core. In the
context of testing, you can override or mock services within ConfigureServices
to isolate components and test their behavior without relying on actual
implementations.
For example, when testing, you can mock external
dependencies such as database contexts, third-party APIs, or services, ensuring
that the unit tests focus on the logic within the controller or service being
tested.
Example:
public class MyControllerTest
{
private readonly MyController
_controller;
public MyControllerTest()
{
var services =
new ServiceCollection();
services.AddScoped<IProductService, MockProductService>(); //
Mocked service for testing
var
serviceProvider = services.BuildServiceProvider();
_controller = new
MyController(serviceProvider.GetService<IProductService>());
}
[Fact]
public void TestGetProducts()
{
var result =
_controller.Get();
Assert.NotNull(result);
}
}
76. What is the difference between DbContext and DbSet in
Entity Framework Core?
Answer:
- DbContext:
Represents the session between the application and the database. It is
used to query and save data. DbContext tracks changes to entities, and it
is used to perform CRUD (Create, Read, Update, Delete) operations on the
data.
- DbSet<T>:
Represents a collection of entities of a specific type that you can query
and perform operations on. Each entity class in your application usually
has a corresponding DbSet in the DbContext.
Example:
public class ApplicationDbContext : DbContext
{
public DbSet<Product> Products {
get; set; } // DbSet of Product
}
In this example, Products is a DbSet representing the
collection of Product entities, and ApplicationDbContext is the DbContext used
to manage the collection and interact with the database.
77. What is the Map function in UseEndpoints in ASP.NET
Core?
Answer: Map is a method used within UseEndpoints
to map specific routes to controllers, Razor Pages, or other endpoints. It
helps in defining how HTTP requests are routed to particular endpoints, like
controller actions or pages.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Maps controller routes to the routing
system
endpoints.MapRazorPages(); // Maps Razor Pages routes
});
}
You can also map specific HTTP methods or actions:
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/hello",
async context =>
{
await
context.Response.WriteAsync("Hello World");
});
});
78. What is IHostedService in ASP.NET Core?
Answer: IHostedService is an interface that is
used to represent a background service in ASP.NET Core. A background service
allows you to perform long-running tasks such as polling, processing messages
from a queue, or running scheduled tasks outside the scope of an HTTP request.
It has two main methods:
- StartAsync(CancellationToken
cancellationToken): Called when the application starts.
- StopAsync(CancellationToken
cancellationToken): Called when the application shuts down.
Example:
public class MyBackgroundService : IHostedService
{
private readonly
ILogger<MyBackgroundService> _logger;
public
MyBackgroundService(ILogger<MyBackgroundService> logger)
{
_logger = logger;
}
public Task StartAsync(CancellationToken
cancellationToken)
{
_logger.LogInformation("Background service starting.");
return
Task.CompletedTask;
}
public Task StopAsync(CancellationToken
cancellationToken)
{
_logger.LogInformation("Background service stopping.");
return
Task.CompletedTask;
}
}
To register the background service in ConfigureServices:
services.AddHostedService<MyBackgroundService>();
79. What is the Authorization middleware used for in
ASP.NET Core?
Answer: The Authorization middleware is used to
authorize users before they access specific resources or perform actions. It
checks if the user has the required permissions (roles, claims, policies) to
access a given resource.
You must configure this middleware after UseAuthentication
because authorization requires that the user has been authenticated.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseAuthorization(); // Enforces
authorization policies
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
You can use attributes like [Authorize] on controllers or
actions to enforce authorization:
[Authorize(Roles = "Admin")]
public IActionResult AdminPage()
{
return View();
}
80. What is Model Binding in ASP.NET Core?
Answer: Model binding in ASP.NET Core is the
process of taking data from HTTP requests (such as form data, query parameters,
or route values) and binding it to method parameters or properties of a model
class. This enables the automatic population of parameters with data from the
request.
ASP.NET Core supports various model binding sources:
- Query
string (?id=1)
- Form
data
- Route
data (/products/1)
- Header
data
- Body
data (for JSON or XML payload)
Example:
[HttpPost]
public IActionResult CreateProduct(Product model)
{
if (ModelState.IsValid)
{
// Use model data
here
return
RedirectToAction("Index");
}
return View(model);
}
In this example, ASP.NET Core automatically binds the
Product model with the data from the request (e.g., form data or query string).
81. What are the various types of middleware in ASP.NET
Core?
Answer: Middleware in ASP.NET Core can be
categorized as:
- Request
Middleware: Handles HTTP requests and processes them (e.g.,
authentication, logging, compression).
- Response
Middleware: Alters the HTTP response before it is sent back to the
client (e.g., setting response headers, logging).
- Error
Handling Middleware: Manages exceptions and displays error pages
(e.g., UseExceptionHandler).
- Routing
Middleware: Determines which route a request should map to (e.g.,
UseRouting).
- Static
File Middleware: Serves static files like images, JavaScript, and CSS
(e.g., UseStaticFiles).
Example:
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
// Routing middleware
app.UseStaticFiles(); //
Static files middleware
app.UseAuthentication(); // Authentication
middleware
app.UseAuthorization(); //
Authorization middleware
app.UseEndpoints(endpoints => {
endpoints.MapControllers(); // MVC Controller routing middleware
});
}
82. What is the difference between POST and PUT HTTP
methods?
Answer:
- POST:
The POST method is used to create a new resource. It is not idempotent,
meaning that sending the same POST request multiple times can create
multiple resources. It is typically used for submitting form data or
uploading files.
- PUT:
The PUT method is used to update an existing resource. It is idempotent,
meaning that sending the same PUT request multiple times will always
result in the same state of the resource.
Example:
- POST:
Creating a new product.
- PUT:
Updating the details of an existing product.
83. What is the role of IConfiguration in ASP.NET Core?
IConfiguration is used to access configuration
settings in an ASP.NET Core application. These settings can be read from
various sources, such as appsettings.json, environment variables, command-line
arguments, or custom providers.
The configuration system is hierarchical,
meaning you can have different configuration files for different environments
(e.g., appsettings.Development.json).
Example:
public class MyService
{
private readonly string
_apiKey;
public
MyService(IConfiguration configuration)
{
_apiKey = configuration.GetValue<string>("AppSettings:ApiKey");
}
}
You can register custom configuration providers
and bind configuration sections to strongly typed objects using IOptions<T>.
Example:
public class AppSettings
{
public string ApiKey {
get; set; }
}
public void
ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}
84. What are IOptions<T>
and IOptionsSnapshot<T> in ASP.NET Core?
Answer:
IOptions<T>: Provides access to configuration
settings. It is typically used for accessing settings that do not change during
the application's lifetime. The configuration is read at the time of
application startup.
IOptionsSnapshot<T>: Used for retrieving
configuration values that can change during the application's lifetime. It is
particularly useful in scenarios where the application can reload configuration
values without restarting (e.g., for settings that change frequently or need to
be updated without restarting the app).
Example:
public class MyService
{
private readonly
AppSettings _appSettings;
public
MyService(IOptions<AppSettings> options)
{
_appSettings = options.Value;
}
}
public class MyServiceWithSnapshot
{
private readonly
AppSettings _appSettings;
public
MyServiceWithSnapshot(IOptionsSnapshot<AppSettings> optionsSnapshot)
{
_appSettings = optionsSnapshot.Value;
}
}
85. What is AddSingleton,
AddScoped, and AddTransient in Dependency Injection (DI)?
Answer:
These methods are used to register services in
the ASP.NET Core dependency injection container with different lifetimes:
AddSingleton: Registers a service as a singleton. The
same instance of the service will be used throughout the application's
lifetime.
AddScoped: Registers a service with a scoped
lifetime. A new instance of the service is created per request (or per scope).
This is commonly used for services like database contexts.
AddTransient: Registers a service with a transient
lifetime. A new instance of the service is created each time it is requested.
This is useful for lightweight services that don’t need to be shared.
Example:
public void
ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILoggingService, LoggingService>(); //
Singleton
services.AddScoped<IProductService,
ProductService>(); // Scoped
services.AddTransient<IEmailService,
EmailService>(); // Transient
}
86. Explain Configure
and ConfigureServices in the Startup.cs file in ASP.NET Core.
Answer:
ConfigureServices: This method is used to add services to
the dependency injection container. It is called by the runtime when the
application starts up. Services like MVC, authentication, database contexts,
logging, and any other dependencies should be added here.
Configure: This method is used to define how the
application will respond to HTTP requests. You configure middleware components
(such as authentication, routing, static files, etc.) in this method.
Example:
public void
ConfigureServices(IServiceCollection services)
{
services.AddMvc(); // Register MVC services
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
if
(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
87. What is Serilog
in ASP.NET Core, and how do you integrate it?
Answer:
Serilog is a structured logging library that
can be used to log events in ASP.NET Core applications. Unlike traditional
logging libraries, Serilog supports structured logging, meaning it logs data in
a structured format (such as JSON) that is easy to analyze and query.
To integrate Serilog, install the Serilog.AspNetCore
NuGet package and configure it in the Program.cs or Startup.cs file.
Example:
public class Program
{
public static void
Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("app.log")
.CreateLogger();
CreateHostBuilder(args).Build().Run();
}
public static
IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog(); // Use Serilog for logging
}
Serilog provides structured logging, making it
more useful for debugging, monitoring, and analyzing log data.
88. What is IActionFilter
and IResultFilter in ASP.NET Core?
Answer:
These are filter interfaces used in ASP.NET
Core for implementing custom behavior before or after an action method runs.
IActionFilter: It is used to execute custom logic
before and after an action method is executed. This interface has two methods:
OnActionExecuting: Called before the action
method is executed.
OnActionExecuted: Called after the action method
is executed.
Example:
public class MyActionFilter :
IActionFilter
{
public void
OnActionExecuting(ActionExecutingContext context)
{
// Logic before action executes
}
public void
OnActionExecuted(ActionExecutedContext context)
{
// Logic after action executes
}
}
IResultFilter: It is used to execute custom logic before and
after the result is executed. This interface is useful when you want to
manipulate the result of an action, such as the view result or JSON result.
Example:
public class MyResultFilter :
IResultFilter
{
public void
OnResultExecuting(ResultExecutingContext context)
{
// Logic before result executes
}
public void
OnResultExecuted(ResultExecutedContext context)
{
// Logic after result executes
}
}
89. What is IWebHostEnvironment and IHostEnvironment in
ASP.NET Core?
Answer:
Both IWebHostEnvironment and IHostEnvironment
provide information about the environment in which an ASP.NET Core application
is running.
IHostEnvironment: Represents the environment for
general background services and console applications. It provides information
about the environment's name (e.g., Development, Staging, Production), and it
is used in general hosting scenarios.
IWebHostEnvironment: It extends IHostEnvironment and
is specifically used for web applications. It provides additional properties
such as WebRootPath (the path to the web root folder) and ContentRootPath (the
path to the content root folder).
Example:
public class MyService
{
private readonly
IWebHostEnvironment _env;
public
MyService(IWebHostEnvironment env)
{
_env = env;
}
public void
DisplayEnvironment()
{
Console.WriteLine($"Environment: {_env.EnvironmentName}");
Console.WriteLine($"Web Root Path: {_env.WebRootPath}");
}
}
90. Explain
Middleware Pipeline in ASP.NET Core.
Answer:
The middleware pipeline in ASP.NET Core is a
series of components that are executed sequentially when an HTTP request is
received. Middleware components are configured in the Configure method of Startup.cs.
They handle requests and responses and can perform tasks such as
authentication, logging, routing, compression, or response modification.
Middleware is typically added using Use methods
(e.g., UseAuthentication, UseRouting, UseStaticFiles). The order in which
middleware is added is critical since the pipeline is executed in the same
order.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseAuthentication(); // Authentication middleware
app.UseAuthorization(); // Authorization middleware
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Middleware is an essential part of the ASP.NET
Core request-processing flow, and it can be used to intercept, modify, or
short-circuit requests.
91. What is the role of AddAuthentication in ASP.NET
Core?
Answer:
AddAuthentication is a method used to configure
authentication services in an ASP.NET Core application. It is called in the ConfigureServices
method and specifies the authentication scheme to be used (e.g., cookies, JWT,
OAuth). It is a key part of the authentication middleware, and you must call UseAuthentication
in the Configure method to ensure authentication occurs in the request
pipeline.
Example:
public void
ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login";
});
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
92. What is the purpose of ConfigureAwait(false) in
asynchronous programming?
Answer: ConfigureAwait(false) is used to avoid
capturing the synchronization context after an await operation. By default,
when await is called, the continuation of the task is posted back to the
original synchronization context (usually the UI thread in a desktop or mobile
app).
By using ConfigureAwait(false), you instruct the code to
continue execution on any available thread, not necessarily the original
thread, which is beneficial for improving performance in background or library
code where you don't need to update the UI.
Example:
public async Task DoSomethingAsync()
{
await
Task.Delay(1000).ConfigureAwait(false);
// The following code will not return to
the original context (UI thread).
}
When to use ConfigureAwait(false):
- In
libraries or background services where you don't need to update UI.
- In
ASP.NET Core, as it does not have a UI thread, but it can help avoid
unnecessary context-switching, especially in high-concurrency scenarios.
93. What is the difference between async and await in C#?
Answer:
- async:
The async keyword is used to define an asynchronous method. It indicates
that the method will contain asynchronous operations, and it allows the
method to return a Task, Task<T>, or ValueTask<T>.
- await:
The await keyword is used within an async method to mark an expression
that will run asynchronously. It pauses the execution of the method until
the awaited task completes. The await keyword must be used inside an async
method.
Example:
public async Task<int> AddAsync(int a, int b)
{
return await Task.Run(() => a + b); //
'await' pauses until the task is completed.
}
Key Points:
- async
enables asynchronous programming.
- await
is used to await an asynchronous operation and doesn't block the thread.
- An
async method will always return Task, Task<T>, or void.
94. What is the Task.WhenAll method and when is it used?
Answer: Task.WhenAll is a method used to run
multiple asynchronous operations concurrently and wait for all of them to
complete. It returns a Task that will complete when all the tasks in the
collection have completed. It is useful when you need to execute several
independent tasks in parallel and wait for all of them to finish.
Example:
public async Task RunTasks()
{
var task1 = Task.Delay(1000);
var task2 = Task.Delay(2000);
var task3 = Task.Delay(3000);
await Task.WhenAll(task1, task2, task3);
// Wait for all tasks to complete
Console.WriteLine("All tasks
completed.");
}
Key Use Cases:
- Running
multiple independent tasks concurrently.
- Waiting
for the completion of all tasks before proceeding.
- Handling
the results from multiple tasks if needed.
95. What are the differences between ValueTask<T>
and Task<T> in C#?
Answer: ValueTask<T> is similar to
Task<T> but is designed to be more efficient in certain scenarios where
the result is available synchronously (without needing to allocate a Task).
ValueTask<T> can be used to avoid unnecessary allocations when the result
of an asynchronous operation is already available.
Key Differences:
- Memory
Allocation: ValueTask<T> avoids heap allocation in cases where
the result is available synchronously.
- Multiple
Awaits: Task<T> can be awaited multiple times, while
ValueTask<T> should only be awaited once. Calling .Result or .Wait()
multiple times on ValueTask<T> may lead to exceptions.
- Performance:
ValueTask<T> can offer better performance when the result is
available synchronously or when the task completes quickly.
Example:
public ValueTask<int> GetValueAsync()
{
return new ValueTask<int>(42); //
Returns synchronously without allocating a Task.
}
When to Use:
- Use
Task<T> when the task will always be asynchronous or when you need
to await the task multiple times.
- Use
ValueTask<T> when the task is often completed synchronously and you
want to avoid unnecessary memory allocations.
96. What is the IDisposable interface and when should you
implement it?
Answer: IDisposable is an interface that
provides a mechanism for releasing unmanaged resources, such as file handles,
network connections, or database connections, when they are no longer needed.
The Dispose method is called to release those resources explicitly.
When to Implement:
- When
your class holds unmanaged resources (e.g., IntPtr, FileStream,
SqlConnection) that need to be manually cleaned up.
- When
your class uses other objects that implement IDisposable and you need to
release them.
Example:
public class MyResource : IDisposable
{
private bool _disposed = false;
public void Dispose()
{
if (!_disposed)
{
// Release unmanaged resources
_disposed = true;
}
// Suppress
finalization to prevent it from being called
GC.SuppressFinalize(this);
}
~MyResource() // Finalizer (optional)
{
Dispose();
}
}
The Dispose method should clean up both managed and
unmanaged resources, and it's common to use a finalizer to ensure resources are
released if Dispose was not called explicitly.
97. Explain the difference between Ref and Out keywords
in C#.
Answer: Both ref and out are used to pass
parameters by reference, but they have distinct behaviors.
- ref:
When a parameter is passed using ref, it must be initialized before being
passed to the method. The method can then modify the value and return it.
- out:
When a parameter is passed using out, it does not need to be initialized
before being passed. The method is required to assign a value to the
parameter before returning.
Example:
public void RefExample(ref int x)
{
x = x + 5; // Can modify the value
}
public void OutExample(out int x)
{
x = 10; // Must initialize the
value
}
Key Differences:
- ref:
Requires the variable to be initialized before being passed.
- out:
Does not require the variable to be initialized, but must be initialized
inside the method.
- Both
ref and out modify the value of the variable passed to the method.
98. What is the difference between abstract class and
interface in C#?
Answer: Both abstract classes and interfaces are
used to define contracts and provide a structure for derived classes to
implement, but there are key differences:
- Abstract
Class:
- Can
contain method implementations as well as method declarations.
- Can
have fields, properties, and constructors.
- Can
have access modifiers (e.g., public, private).
- A
class can inherit from only one abstract class (single inheritance).
- Interface:
- Can
only contain method declarations (prior to C# 8.0, it could not contain
any method implementations).
- Cannot
have fields or constructors.
- Methods
in interfaces are always public by default and cannot have access
modifiers.
- A
class can implement multiple interfaces (multiple inheritance).
Example:
// Abstract Class
public abstract class Animal
{
public abstract void Speak(); // Abstract
method
}
// Interface
public interface IAnimal
{
void Speak(); // No method body, just a
declaration
}
When to Use:
- Use
an abstract class when you want to provide shared
functionality or common state (fields, constructors).
- Use
an interface when you want to define a contract that
multiple classes can implement without enforcing any shared
implementation.
99. What is the purpose of the volatile keyword in C#?
Answer: The volatile keyword in C# is used to
indicate that a field can be modified by multiple threads. It tells the
compiler to always fetch the value of the field from memory rather than using a
cached value. This ensures that the value is not optimized or cached, which
could lead to inconsistent or outdated data in a multi-threaded environment.
Example:
private volatile bool _isRunning;
public void Stop()
{
_isRunning = false; // This change will
be immediately visible to all threads
}
Key Points:
- volatile
is useful in multi-threaded environments when a variable may be accessed
or modified by multiple threads.
- It
ensures that the field's value is always fetched directly from memory and
not cached.
100. What is the lock keyword in C# and how does it work?
Answer: The lock keyword is used to ensure that
only one thread can access a critical section of code at a time. It prevents
race conditions when multiple threads are trying to modify shared resources.
The lock statement works by acquiring a mutual-exclusion
lock on an object. Once the lock is acquired, no other thread can enter the
locked code until the lock is released.
Example:
private static readonly object _lockObj = new object();
public void Increment()
{
lock (_lockObj)
{
// Critical
section
_counter++;
// Only one thread can enter this block at a time
}
}
Key Points:
- The
object used in the lock statement should be
a private object, such as a readonly field.
- The
lock keyword ensures that only one thread can access the critical section
at a time, preventing race conditions.
101. What is Dependency Injection (DI) and why is it
important in ASP.NET Core?
Answer: Dependency Injection (DI) is a design
pattern that allows the injection of dependent objects (services) into a class,
rather than having the class create them itself. DI is an important part of
ASP.NET Core because it promotes loose coupling, testability, and separation of
concerns.
Why DI is important in ASP.NET Core:
- It
allows better control over dependencies and helps in managing object
lifetimes.
- It
improves testability by making it easier to mock or substitute
dependencies during unit testing.
- It
simplifies the configuration and maintenance of complex systems.
Example of registering a service using DI:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IMyService,
MyService>(); // Registers MyService with transient lifetime
}
Example of injecting a dependency into a controller:
public class HomeController : Controller
{
private readonly IMyService _myService;
public HomeController(IMyService
myService)
{
_myService =
myService;
}
public IActionResult Index()
{
var data =
_myService.GetData();
return
View(data);
}
}
102. What are Middleware components in ASP.NET Core?
Answer: Middleware components are software
components that are assembled into an application pipeline to handle requests
and responses. In ASP.NET Core, middleware components are executed in the order
they are added in the Configure method of the Startup class.
Each middleware component can perform operations like
logging, authentication, routing, exception handling, etc., and then either
pass control to the next middleware or terminate the request.
Example of adding middleware:
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
// Code before
passing control to the next middleware
await next();
// Code after
passing control back from the next middleware
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Key points:
- Middleware
is executed in the order it is added.
- It
can modify the request and response or handle the request directly.
- Common
middleware includes UseRouting(), UseAuthorization(), and
UseStaticFiles().
103. What is the IHostedService interface in ASP.NET
Core?
Answer: IHostedService is an interface in
ASP.NET Core that provides a way to run background tasks during the lifecycle
of the application. It allows you to start long-running tasks when the
application starts and stop them gracefully when the application shuts down.
Methods of IHostedService:
- StartAsync(CancellationToken
cancellationToken): This method is called when the application starts.
You can run your background tasks here.
- StopAsync(CancellationToken
cancellationToken): This method is called when the application is
stopping. It is used to clean up resources or stop background tasks.
Example of implementing IHostedService:
public class MyBackgroundService : IHostedService
{
private Timer _timer;
public Task StartAsync(CancellationToken
cancellationToken)
{
_timer = new
Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
return
Task.CompletedTask;
}
private void DoWork(object state)
{
// Perform
background work
Console.WriteLine("Background task is running");
}
public Task StopAsync(CancellationToken
cancellationToken)
{
_timer?.Dispose();
return
Task.CompletedTask;
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<MyBackgroundService>();
}
Use Cases:
- Running
scheduled tasks, background jobs, or periodic jobs.
- Executing
cleanup tasks when the application stops.
104. What is the ActionResult<T> in ASP.NET Core
and how does it work?
Answer: ActionResult<T> is a wrapper used
to return both a result (of type T) and an HTTP status code. It allows you to
return different types of responses from a controller action, including both
success and error responses, and still maintain the benefits of type safety.
This is useful when you want to return different types of
responses like JSON data (OkObjectResult), errors (NotFoundResult,
BadRequestResult), or a simple result (OkResult), while still encapsulating a
value of type T.
Example:
public class MyController : ControllerBase
{
public ActionResult<string> Get()
{
string data =
"Hello, World!";
return
Ok(data); // Returns HTTP 200 with the string data
}
}
Benefits:
- Simplifies
response handling by allowing both data and status codes to be returned
easily.
- Helps
to maintain cleaner, more readable code when working with different types
of HTTP responses.
105. What is the ServiceLifetime in ASP.NET Core and what
are its types?
Answer: In ASP.NET Core, ServiceLifetime defines
how long a service instance is available during the application’s lifetime.
There are three main types of ServiceLifetime:
- Singleton:
A single instance of the service is created and shared throughout the
application's lifetime. It is useful for services that maintain state or
share resources.
- Scoped:
A new instance of the service is created per request or per scope. This is
often used for services like database contexts that need to be disposed of
after a request is processed.
- Transient:
A new instance of the service is created every time it is requested. This
is useful for lightweight services that do not hold state or need to be
shared.
Example of service registration:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IMyService,
MyService>(); // Singleton
services.AddScoped<IMyService,
MyService>(); // Scoped
services.AddTransient<IMyService,
MyService>(); // Transient
}
Key points:
- Singleton:
Same instance throughout the application.
- Scoped:
New instance per request/operation.
- Transient:
New instance each time it is requested.
106. What are HttpClientFactory and why is it important
in ASP.NET Core?
Answer: HttpClientFactory is a factory
introduced in ASP.NET Core 2.1 that provides a centralized, managed way to
configure and create HttpClient instances. It helps to avoid issues like socket
exhaustion that can occur when HttpClient instances are not reused properly.
Benefits of HttpClientFactory:
- Avoids
Socket Exhaustion: Ensures proper reuse of HttpClient instances,
preventing the creation of too many sockets.
- Centralized
Configuration: Allows you to configure common settings such as
headers, timeouts, or base addresses for all HttpClient instances.
- Polly
Integration: Integrates with Polly for handling transient faults such
as retries, circuit breakers, etc.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("MyClient", client =>
{
client.BaseAddress = new Uri("https://api.example.com");
client.DefaultRequestHeaders.Add("User-Agent", "MyApp");
});
}
public class MyService
{
private readonly IHttpClientFactory
_clientFactory;
public MyService(IHttpClientFactory
clientFactory)
{
_clientFactory =
clientFactory;
}
public async Task<string>
GetDataAsync()
{
var client =
_clientFactory.CreateClient("MyClient");
var response =
await client.GetAsync("/data");
return await
response.Content.ReadAsStringAsync();
}
}
When to Use:
- When
you need to create and manage multiple HttpClient instances.
- When
making external HTTP requests with retries, timeouts, or base addresses.
107. What are Action Filters in ASP.NET Core and how do
they work?
Answer: Action Filters are used to
execute code before and after an action method is called in an MVC controller.
They can be used to handle tasks such as logging, validation, or custom
authorization.
Types of Action Filters:
- OnActionExecuting:
Called before an action method is executed.
- OnActionExecuted:
Called after an action method is executed.
You can implement action filters by inheriting from
ActionFilterAttribute or implementing IActionFilter directly.
Example of an Action Filter:
public class MyActionFilter : ActionFilterAttribute
{
public override void
OnActionExecuting(ActionExecutingContext context)
{
// Logic before
the action executes
}
public override void
OnActionExecuted(ActionExecutedContext context)
{
// Logic after
the action executes
}
}
[MyActionFilter]
public class MyController : Controller
{
public IActionResult Index()
{
return View();
}
}
When to Use:
- For
cross-cutting concerns like logging, security, or modifying the
request/response.
- To
apply behavior before or after a controller action is executed.
108. What is the purpose of appsettings.json and how is
it used in ASP.NET Core?
Answer: appsettings.json is a configuration file
in ASP.NET Core that stores key-value pairs for configuration settings, such as
application settings, connection strings, or external service configurations.
It allows you to centralize configuration outside of code and makes it easy to
manage different environments (Development, Staging, Production).
Example:
{
"AppSettings": {
"ApiKey": "your-api-key-here"
},
"ConnectionStrings": {
"DefaultConnection":
"Server=myServerAddress;Database=myDataBase;User
Id=myUsername;Password=myPassword;"
}
}
You can access these values using the IConfiguration
interface:
public class MyService
{
private readonly IConfiguration
_configuration;
public MyService(IConfiguration
configuration)
{
_configuration =
configuration;
}
public void DisplayApiKey()
{
var apiKey =
_configuration["AppSettings:ApiKey"];
Console.WriteLine(apiKey);
}
}
When to Use:
- To
centralize configuration for an ASP.NET Core application.
- To
manage settings that might change between environments (e.g., connection
strings, API keys).
- Supports
environment-specific overrides, like appsettings.Development.json.
109. What is the difference between AddSingleton,
AddScoped, and AddTransient in dependency injection?
Answer: These three methods define the lifetime of
a service in dependency injection (DI) in ASP.NET Core.
- AddSingleton:
- The
service is created once and shared throughout the application's lifetime.
- Useful
for services that hold state or are expensive to create, such as
configuration settings or logging services.
- Example:
Database connection pool, caching services.
- When
to Use: When you need a single instance of the service across the
entire application.
- AddScoped:
- A
new instance is created once per request (or per scope
in a unit of work).
- Useful
for services like database contexts that should be disposed of after a
request.
- When
to Use: When the service requires a new instance per request (i.e.,
per HTTP request in a web app).
- AddTransient:
- A
new instance of the service is created each time it is requested.
- Useful
for lightweight services that do not hold state and can be instantiated
without a significant performance hit.
- When
to Use: When the service doesn't maintain state and should be created
fresh every time it's requested.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IMyService,
MyService>(); // Singleton
services.AddScoped<IMyService,
MyService>(); // Scoped
services.AddTransient<IMyService,
MyService>(); // Transient
}
110. What is the Configure method in ASP.NET Core's
Startup class?
Answer: The Configure method in ASP.NET Core's
Startup class is used to define the middleware pipeline that
handles requests and responses. It is where you configure how the application
should respond to HTTP requests. You add middleware components to the pipeline,
such as authentication, routing, static file handling, etc.
Example of a Configure method:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage(); // Development-specific middleware
}
else
{
app.UseExceptionHandler("/Home/Error"); // Production-specific
middleware
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Key Points:
- The
order in which middleware is added to the pipeline is crucial because the
request will flow through them in the order they are added.
- The
Configure method is invoked at runtime to set up HTTP request processing.
- Common
middleware includes UseRouting(), UseAuthentication(), and UseEndpoints().
111. What is the IConfiguration interface and how does it
work in ASP.NET Core?
Answer: The IConfiguration interface in ASP.NET
Core is used to access configuration settings from different sources, such as
appsettings.json, environment variables, or command-line arguments.
How it works:
- Configuration
sources: ASP.NET Core supports multiple configuration sources, and
they are combined in a hierarchy. The IConfiguration instance is created
and populated from these sources.
- Accessing
values: You can access values using the IConfiguration interface by
specifying the key.
Example of loading configuration from appsettings.json:
// appsettings.json
{
"AppSettings": {
"ApiUrl": "https://api.example.com"
}
}
public class MyService
{
private readonly IConfiguration
_configuration;
public MyService(IConfiguration
configuration)
{
_configuration =
configuration;
}
public string GetApiUrl()
{
var apiUrl =
_configuration["AppSettings:ApiUrl"];
return apiUrl;
}
}
Key Features:
- Supports
hierarchical data.
- Allows
accessing configuration values via key paths (e.g.,
"AppSettings:ApiUrl").
- Configuration
can be injected into classes via constructor injection.
112. What is the purpose of IActionResult in ASP.NET
Core?
Answer: IActionResult is an interface that
represents the result of an action method in ASP.NET Core MVC and Web API
controllers. It allows you to return various types of responses, such as HTML
views, JSON data, redirects, or error responses.
Common ActionResult Implementations:
- Ok():
Returns a 200 OK response with the specified data (usually used for API
responses).
- NotFound():
Returns a 404 Not Found response.
- BadRequest():
Returns a 400 Bad Request response, often used for validation errors.
- RedirectToAction():
Returns a redirection to a different action.
- View():
Returns a view result in MVC.
Example:
public IActionResult GetUser(int id)
{
var user = _userService.GetUser(id);
if (user == null)
{
return
NotFound(); // Return 404 if user not found
}
return Ok(user); // Return 200 OK with
user data
}
Benefits:
- It
provides a flexible way to return different types of HTTP responses from a
single action.
- It
helps to decouple the action result logic from specific response formats
(e.g., JSON, views).
113. What is the ActionResult<T> type in ASP.NET
Core?
Answer: ActionResult<T> is a return type
that combines both an action result (such as HTTP status code and response
message) and a data type (T). It provides a more structured and cleaner way to
return results from controller actions in Web API applications.
- It
allows you to return a strongly typed object (T) along with an HTTP status
code.
- It
helps improve type safety and makes the response handling more flexible.
Example:
public ActionResult<User> GetUser(int id)
{
var user = _userService.GetUser(id);
if (user == null)
{
return
NotFound(); // Return 404 if user not found
}
return Ok(user); // Return 200 OK with
user data
}
In this case, ActionResult<User> combines the HTTP
status code (e.g., Ok(), NotFound()) with a user object, and the response is
both strongly typed and flexible.
114. What is the difference between IEnumerable<T>
and IQueryable<T> in C#?
Answer: Both IEnumerable<T> and
IQueryable<T> are interfaces used for querying collections, but they
differ in how and when the queries are executed.
- IEnumerable<T>:
- Represents
a collection that can be enumerated.
- Works
with in-memory collections (like arrays or lists).
- Queries
are executed in-memory.
- It
is best suited for collections that are already in memory.
- IQueryable<T>:
- Extends
IEnumerable<T> and represents a collection that can be queried
using LINQ.
- It
is designed for working with remote data sources (such as databases).
- Queries
are deferred and executed at the point of
enumeration (when you actually iterate over the collection or
force the evaluation).
- It
allows for more complex queries and performs query translation (e.g.,
converting LINQ queries into SQL for a database).
Example:
IQueryable<User> usersQueryable =
dbContext.Users.Where(u => u.Age > 18);
IEnumerable<User> usersEnumerable =
usersQueryable.ToList(); // Forces evaluation
Key Difference:
- IQueryable<T>
is designed for querying remote sources, like a database, and it defers
execution, allowing for optimized queries (e.g., SQL generation).
- IEnumerable<T>
is used for in-memory collections and queries are executed immediately.
115. Explain the async and await keywords in C#.
Answer:
- async:
- The
async modifier is used to define asynchronous methods.
- It
indicates that the method will contain one or more await expressions and
may involve asynchronous operations.
- The
return type of an async method must be Task, Task<T>, or void (for
event handlers).
- The
async method allows the program to continue execution without blocking
the main thread.
- await:
- The
await keyword is used to wait for the completion of an asynchronous
operation.
- When
await is called on a Task or Task<T>, the method execution is
paused until the task completes, allowing the thread to perform other
tasks.
- It
is only allowed in methods marked with the async modifier.
Example:
public async Task<int> GetDataAsync()
{
var data = await
SomeLongRunningOperationAsync(); // Non-blocking await
return data;
}
Key Points:
- async
allows you to mark a method for asynchronous execution.
- await
is used inside async methods to pause execution until a
Task is completed, ensuring non-blocking I/O operations.
116. What are ValueTask and when should you use it?
Answer: ValueTask is a type introduced in C# 7.0
for scenarios where you want to return a result asynchronously but want to
avoid the overhead of allocating a Task when the result is already available.
- When
to Use ValueTask:
- When
the operation may return a result synchronously (such as returning an
already computed value or cached result).
- When
you want to minimize the overhead of creating a Task for simple or fast
operations.
Example:
public ValueTask<int> GetNumberAsync()
{
if (cache.Contains("number"))
{
return new
ValueTask<int>((int)cache["number"]);
}
return new
ValueTask<int>(SomeLongRunningAsync());
}
Key Points:
- ValueTask
is more lightweight than Task when an asynchronous method may sometimes
return a result synchronously.
- It
avoids unnecessary heap allocation for synchronous results.
117. What is the difference between IActionResult and
ActionResult<T> in ASP.NET Core?
Answer: IActionResult and ActionResult<T>
are both return types used in controller action methods in ASP.NET Core, but
they have significant differences:
- IActionResult:
- Represents
the result of an action method in a controller.
- It
can return various response types, such as Ok(), NotFound(), Redirect(),
etc.
- It
is more flexible because it allows you to return any kind of result (like
a view or a JSON response).
- ActionResult<T>:
- This
is a generic type that combines an action result with a strongly-typed
response (T).
- It
is typically used in Web APIs when you want to return a specific data
type (like a model or entity) alongside the HTTP status code.
- The
primary benefit is type safety and clarity, as the action method will
always return a specific type (T), such as a User model.
Example:
public IActionResult GetUser(int id)
{
var user = _userService.GetUserById(id);
if (user == null)
{
return
NotFound();
}
return Ok(user); // ActionResult with any
response type
}
public ActionResult<User> GetUser(int id)
{
var user = _userService.GetUserById(id);
if (user == null)
{
return
NotFound();
}
return Ok(user); // ActionResult with a
strongly-typed model
}
Key Difference:
- IActionResult
is more general and flexible, used in MVC scenarios where you may return a
variety of results.
- ActionResult<T>
is specific to API scenarios where you return a strongly-typed object,
with the benefits of both HTTP status codes and strong typing.
118. What is middleware in ASP.NET Core and how does it
work?
Answer: Middleware in ASP.NET Core refers to
components that are assembled into an application pipeline to handle HTTP
requests and responses. Each middleware component has access to the HTTP
request and response, and it can perform actions such as logging,
authentication, or modifying the request/response before passing it to the next
component in the pipeline.
- Middleware
components are executed in the order they are added to the Configure
method in the Startup.cs class.
- Each
middleware can either pass the request to the next middleware in the
pipeline or terminate the request (by generating a response directly).
Example:
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<MyCustomMiddleware>(); // Custom middleware
app.UseRouting(); // Routing middleware
app.UseEndpoints(endpoints => {
endpoints.MapControllers(); // Endpoint routing middleware
});
}
Types of Middleware:
- Built-in
Middleware: Examples include UseRouting(), UseStaticFiles(),
UseAuthentication(), etc.
- Custom
Middleware: You can create custom middleware to handle specific logic
(e.g., logging, error handling).
Middleware Pipeline:
- Requests
are processed in the order they are configured in the Configure method.
- Middleware
can modify the request and response, handle exceptions, or end the
request-response cycle.
119. What are the common types of middleware in ASP.NET
Core?
Answer: ASP.NET Core provides several built-in
middleware types that serve different purposes in the request-response
pipeline. Some common types include:
- Routing
Middleware (UseRouting()):
- Determines
how requests should be routed to the appropriate controllers, actions, or
pages.
- Authentication
Middleware (UseAuthentication()):
- Adds
authentication functionality to the pipeline by validating the user's
credentials.
- Authorization
Middleware (UseAuthorization()):
- Adds
authorization checks after authentication, ensuring the user has the
required permissions to access a resource.
- Static
Files Middleware (UseStaticFiles()):
- Serves
static files (e.g., images, JavaScript, CSS files) from the file system.
- Session
Middleware (UseSession()):
- Manages
user session data, storing it between requests.
- Exception
Handling Middleware (UseExceptionHandler()):
- Captures
exceptions thrown during request processing and redirects to an error
page or logs the exception.
- CORS
Middleware (UseCors()):
- Allows
or denies cross-origin requests from web browsers.
Example:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // Serve static
files
app.UseRouting(); // Route the request
app.UseAuthentication(); // Authenticate
the user
app.UseAuthorization(); // Authorize the
user
app.UseEndpoints(endpoints => {
endpoints.MapControllers(); // Map endpoints
});
}
120. Explain the concept of Dependency Injection (DI) in
ASP.NET Core.
Answer: Dependency Injection (DI) is a design
pattern that allows you to inject dependencies (services) into a class, rather
than having the class create them itself. In ASP.NET Core, DI is built into the
framework, which allows developers to manage dependencies in a central
container and inject them into classes when needed.
DI promotes loose coupling between classes and increases
testability by allowing you to easily mock dependencies.
Types of DI in ASP.NET Core:
- Constructor
Injection: Dependencies are provided through the class constructor.
- Property
Injection: Dependencies are provided through public properties (less
common).
- Method
Injection: Dependencies are provided through method parameters.
Example of Constructor Injection:
public class MyService
{
private readonly IEmailService
_emailService;
public MyService(IEmailService
emailService)
{
_emailService =
emailService;
}
public void SendEmail(string email)
{
_emailService.Send(email);
}
}
Registering Services: You register services in the
ConfigureServices method of Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IEmailService,
EmailService>(); // Register service with DI container
}
Benefits:
- Decouples
classes from their dependencies.
- Makes
unit testing easier by allowing the injection of mock dependencies.
- Simplifies
the management of service lifetimes (singleton, scoped, transient).
121. What are the different service lifetimes in ASP.NET
Core Dependency Injection?
Answer: ASP.NET Core DI provides three service
lifetimes to control the duration and sharing of service instances across
requests:
- Singleton (AddSingleton):
- A
single instance of the service is created and shared across the entire
application's lifetime.
- The
instance is created once when the application starts and is used for all
subsequent requests.
- Suitable
for stateless, thread-safe services or services that need to be shared
across the entire app (e.g., logging, caching).
Example:
services.AddSingleton<ILogger, Logger>();
- Scoped (AddScoped):
- A
new instance of the service is created per request (or
per scope in the application).
- Typically
used for services that work with request-specific data, such as database
contexts.
- The
instance is disposed of at the end of the request.
Example:
services.AddScoped<IDataService, DataService>();
- Transient (AddTransient):
- A
new instance of the service is created every time it is requested.
- Suitable
for lightweight, stateless services that do not hold state across
requests.
Example:
services.AddTransient<IEmailSender, EmailSender>();
122. What is Entity Framework Core and how does it differ
from traditional Entity Framework?
Answer: Entity Framework Core (EF Core) is
a lightweight, cross-platform version of Entity Framework (EF) that
is designed to work with modern .NET Core applications. EF Core allows
developers to interact with databases using an object-oriented approach (ORM),
providing an abstraction layer over the underlying database.
Key Differences:
- Cross-platform:
EF Core supports multiple platforms, including Windows, Linux, and macOS,
whereas the traditional EF was primarily focused on Windows and the .NET
Framework.
- Lightweight:
EF Core is designed to be lighter and more modular than EF, with a smaller
API surface.
- Performance:
EF Core offers improved performance compared to EF, particularly in
scenarios like batch operations and querying.
- No
Visual Designer: Unlike EF, which included a visual designer for
models, EF Core relies more heavily on code-based configuration and
migrations.
- More
Features: EF Core includes new features not available in the
traditional EF, such as in-memory databases, better support for NoSQL
databases, and support for non-relational databases like SQLite and Cosmos
DB.
Example (Defining a DbContext in EF Core):
public class MyDbContext : DbContext
{
public DbSet<User> Users { get;
set; }
}
EF Core provides:
- Migrations
to evolve the database schema.
- Support
for LINQ queries.
- Integration
with various relational and NoSQL databases.
123. Explain the concept of "In-Memory
Database" in Entity Framework Core.
Answer: An In-Memory Database in
EF Core is a lightweight database that runs entirely in memory, useful for
testing and prototyping. It is not persistent, so any data stored in it will be
lost when the application stops.
- The In-Memory
Database is typically used for unit testing and small-scale data
storage during development.
- It
is an in-memory implementation of a database provider and supports all
basic CRUD operations.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseInMemoryDatabase("TestDatabase"));
}
Benefits:
- Fast
and easy to set up.
- Ideal
for testing scenarios where database persistence is not required.
- Mimics
real database behavior without requiring an actual database.
124. What is the role of ConfigureServices and Configure
methods in the Startup class?
Answer: In ASP.NET Core, the Startup class is
used to configure services and middleware for the application. The
ConfigureServices and Configure methods serve different purposes:
- ConfigureServices:
- This
method is used to register services required by the
application in the Dependency Injection (DI) container.
- Services
like MVC, authentication, logging, and database contexts are configured
here.
- This
method is executed before the Configure method, so services are available
for middleware in the request pipeline.
Example:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IUserService,
UserService>();
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
· Configure:
o This
method is used to set up the middleware pipeline, which handles the
request-response lifecycle.
o You
add middleware components in this method, such as authentication, routing,
static file handling, and error handling.
o It
runs after the services are configured, and it’s responsible for handling
requests based on the services you have registered.
Example:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
125. What is the IApplicationBuilder interface in ASP.NET
Core and what are its main methods?
Answer: IApplicationBuilder is an interface used
to configure the HTTP request pipeline in the Configure method of the Startup
class. It provides methods to add middleware components that handle requests
and responses.
Key methods:
Use: Adds custom middleware to the pipeline.
app.Use(async (context, next)
=>
{
// Custom
logic before the request
await
next.Invoke();
// Custom
logic after the request
});
UseRouting: Adds routing middleware to the pipeline
to match the incoming requests to routes.
app.UseRouting();
UseEndpoints: Defines the endpoints for your
application (such as controllers or Razor Pages).
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
UseAuthentication: Adds authentication middleware to
the pipeline to validate users' identities.
app.UseAuthentication();
UseAuthorization: Adds authorization middleware to
enforce authorization policies.
app.UseAuthorization();
UseStaticFiles: Adds middleware to serve static files
(e.g., HTML, CSS, JS).
app.UseStaticFiles();
126. What are the different ways to handle exceptions in
ASP.NET Core?
Answer: In ASP.NET Core, you can handle
exceptions in various ways to provide appropriate responses and logging:
- Global
Exception Handling (via Middleware):
- You
can create custom middleware to catch exceptions globally. A typical
pattern is to catch unhandled exceptions and return a custom error
response.
Example of global exception handling middleware:
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;
public
ExceptionHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext
httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception
ex)
{
// Log the exception or return a custom error response
httpContext.Response.StatusCode = 500;
await httpContext.Response.WriteAsync($"Something went wrong:
{ex.Message}");
}
}
}
- Exception
Handling in Configure Method:
- Use
built-in middleware like UseExceptionHandler or
UseDeveloperExceptionPage.
Example:
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage(); // Detailed error page for development
}
else
{
app.UseExceptionHandler("/Home/Error"); // Redirect to a custom error
page in production
app.UseHsts();
}
}
- Try-Catch
in Controller Actions:
- You
can also wrap code in a try-catch block inside your controller action
methods for finer control over handling exceptions for specific
scenarios.
Example:
public IActionResult GetUser(int id)
{
try
{
var user =
_userService.GetUserById(id);
return Ok(user);
}
catch (Exception ex)
{
return
StatusCode(500, "Internal Server Error: " + ex.Message);
}
}
- Logging:
- You
can log the exception details to a logging framework like Serilog, NLog,
or the built-in ILogger interface in ASP.NET Core.
- Use
ILogger to capture and log detailed exception information for
troubleshooting.
Example:
public class MyController : ControllerBase
{
private readonly
ILogger<MyController> _logger;
public
MyController(ILogger<MyController> logger)
{
_logger = logger;
}
public IActionResult GetUser(int id)
{
try
{
var user = _userService.GetUserById(id);
return Ok(user);
}
catch (Exception
ex)
{
_logger.LogError($"Error getting user: {ex.Message}");
return StatusCode(500, "Internal Server Error");
}
}
}
127. What is the IEnumerable interface in C# and how does
it differ from IQueryable?
Answer: IEnumerable<T> and
IQueryable<T> are both interfaces in C# used for working with collections
and querying data. However, they differ in how and when queries are executed:
- IEnumerable<T>:
- Represents
an in-memory collection of data that can be enumerated.
- It
works with in-memory collections such as arrays, lists, and collections
that implement IEnumerable.
- The
queries are executed in-memory after the collection is
loaded.
Example:
IEnumerable<User> users = dbContext.Users.Where(u
=> u.Age > 30).ToList();
- IQueryable<T>:
- Represents
a queryable collection of data that is not yet executed.
- It
works with remote data sources, such as databases, and allows for
deferred execution. It is used by LINQ to SQL or Entity Framework to
translate LINQ queries into SQL commands.
- The
query is not executed until enumerated, and the database
query is sent only when you iterate over the data (e.g., with .ToList()).
Example:
IQueryable<User> usersQueryable =
dbContext.Users.Where(u => u.Age > 30);
Key Differences:
- IEnumerable<T>
works in memory, suitable for in-memory collections.
- IQueryable<T>
works with remote data sources (e.g., databases) and supports deferred
execution and query translation to SQL.
128. What is the difference between synchronous and
asynchronous programming in C#?
Answer: In C#, synchronous and asynchronous programming
represent two different models for executing tasks, especially I/O-bound
operations.
- Synchronous
Programming:
- Operations
are performed one after another, blocking the current thread until the
task completes.
- Synchronous
code can make the application unresponsive, especially when dealing with
long-running operations (e.g., file I/O, database queries).
Example of synchronous method:
public void ProcessData()
{
// Simulate a blocking I/O operation
Thread.Sleep(5000);
Console.WriteLine("Data
Processed");
}
- Asynchronous
Programming:
- Allows
non-blocking execution by running operations in the background and
letting other tasks execute in the meantime.
- It
improves responsiveness by not blocking the main thread, especially for
I/O-bound operations.
- C#
achieves asynchrony using the async and await keywords.
Example of asynchronous method:
public async Task ProcessDataAsync()
{
// Simulate a non-blocking I/O operation
await Task.Delay(5000);
Console.WriteLine("Data
Processed");
}
Key Differences:
- Synchronous methods
block the thread while performing tasks.
- Asynchronous methods
use Task and do not block the thread, allowing other operations to proceed
while waiting for the task to complete.
129. What is async and await in C# and how do they
improve performance?
Answer:
- async is
a modifier applied to methods, lambdas, or anonymous methods to indicate
that they are asynchronous and can be awaited.
- await is
used inside an async method to call an asynchronous operation, without
blocking the calling thread.
Key Points:
- When
await is used, the method runs asynchronously and doesn’t block the
thread, enabling other operations to continue.
- async
and await improve performance by allowing I/O-bound operations (like web
requests or database calls) to be handled without blocking the thread,
freeing the thread to handle other requests.
Example:
public async Task<int> GetDataAsync()
{
var result = await Task.Run(() =>
LongRunningOperation());
return result;
}
Comments
Post a Comment