.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:

  1. Define a class that implements the IMiddleware interface or simply use a delegate that accepts HttpContext.
  2. 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:

  1. 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>();

  1. 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>();

  1. 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

Popular posts from this blog

Multiline to singleline IN C# - CODING

EF Core interview questions for beginners

EF Core interview questions for experienced