Tag - .NET-Framework

C# Optimization Performance Tips
Jul 18, 2024

Before diving into optimization techniques, it’s important to identify the areas of your code that require improvement. By measuring and profiling your application’s performance, you can pinpoint the exact bottlenecks and focus your optimization efforts where they matter the most (Measure and Identify Bottlenecks). In this blog, I’ll explain effective strategies for handling memory and reducing garbage collection overhead in your C# applications. Memory management and garbage collection are essential aspects of performance tuning in C#, so these best practices will help you optimize your code for maximum efficiency.  Here are 8 tips that will help with performance optimization. 1. Use the IDisposable interface :  Utilizing the IDisposable interface is a crucial C# performance tip. It helps you properly manage unmanaged resources and ensures that your application’s memory usage is efficient.  Bad way: public class ResourceHolder { private Stream _stream; public ResourceHolder(string filePath) { _stream = File.OpenRead(filePath); } // Missing: IDisposable implementation } Good way: public class ResourceHolder : IDisposable { private Stream _stream; public ResourceHolder(string filePath) { _stream = File.OpenRead(filePath); } public void Dispose() { _stream?.Dispose(); // Properly disposing the unmanaged resource. } } By implementing the IDisposable interface, you ensure that unmanaged resources will be released when no longer needed, preventing memory leaks and reducing pressure on the garbage collector. This is a fundamental code optimization technique in C# that developers should utilize. 2. Asynchronous Programming with async/await  Asynchronous programming is a powerful technique for improving C# performance in I/O-bound operations, allowing you to enhance your app’s responsiveness and efficiency. Here, we’ll explore some best practices for async/await in C#. Limit the number of concurrent operations Bad way: public async Task ProcessManyItems(List<string> items) { var tasks = items.Select(async item => await ProcessItem(item)); await Task.WhenAll(tasks); } Good way: public async Task ProcessManyItems(List<string> items, int maxConcurrency = 10) { using (var semaphore = new SemaphoreSlim(maxConcurrency)) { var tasks = items.Select(async item => { await semaphore.WaitAsync(); // Limit concurrency by waiting for the semaphore. try { await ProcessItem(item); } finally { semaphore.Release(); // Release the semaphore to allow other operations. } }); await Task.WhenAll(tasks); } } Without limiting concurrency, many tasks will run simultaneously, which can lead to heavy load and degraded overall performance. Instead, use a SemaphoreSlim to control the number of concurrent operations.  3. UseConfigureAwait(false) when possible ConfigureAwait(false) is a valuable C# performance trick that can help prevent deadlocks in your async code and improve efficiency by not forcing continuations to run on the original synchronization context.   public async Task<string> DataAsync() { var data = await ReadDataAsync().ConfigureAwait(false); // Use ConfigureAwait(false) to avoid potential deadlocks. return ProcessData(data); } 4. Parallel Computing and Task Parallel Library This will help the power of multicore processors and speed up CPU-bound operations Bad way: private void Data(List<int> data) { for (int i = 0; i < data.Count; i++) { PerformExpensiveOperation(data[i]); } } Good way: private void Data(List<int> data) { Parallel.ForEach(data, item => PerformExpensiveOperation(item)); } Parallel loops can considerably accelerate processing of large collections by distributing the workload among multiple CPU cores. Switch from regular for and foreach loops to their parallel counterparts whenever it’s feasible and safe.  5. Importance of Caching Data Utilizing in-memory caching can drastically reduce time-consuming database fetches and speed up your application. The good way demonstrates the use of in-memory caching to store product data and reduce time-consuming database fetches.  6. Optimizing LINQ Performance Force immediate execution using ToList() or ToArray() when needed. Use the AsParallel() extension method to ensure safety and parallelism. Selecting a HashSet instead of a List offers faster look-up times and greater performance 7. Task and ValueTask for reusing asynchronous code Use ValueTask to reduce heap allocations public async ValueTask<string> DataAsync() { var data = await ReadFromStreamAsync(_stream); return ProcessData(data); } By switching from Task<TResult> to ValueTask<TResult>, you can reduce heap allocations and ultimately improve your C# performance 8. Use HttpClientFactory to manage HttpClient instances private readonly HttpClient _httpClient; public MyClass(HttpClient httpClient) { _httpClient = httpClient; } public async Task GetDataAsync() { var response = await _httpClient.GetAsync("http://himashu.com/data"); } This approach manages the lifetimes of your HttpClient instances more efficiently, preventing socket exhaustion. - Use null-coalescing operators (??, ??=) string datInput = NullableString() ?? "default"; - Using Span and Memory for efficient buffer management // Using Span<T> avoids additional memory allocation and copying byte[] data = GetData(); Span<byte> dataSpan = data.AsSpan(); ProcessData(dataSpan); - Use StringComparison options for efficient string comparison bool equal = string.Equals(string1, string2, StringComparison.OrdinalIgnoreCase); - Use StringBuilder over string concatenation in loops StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.AppendFormat("Iteration: {0}", i); } string result = sb.ToString();   This has been a collection of just a few things I’ve found useful for enhancing the performance of my C# .NET code. Remember that the key to successful development is a balance between code quality and performance optimizations. By employing these techniques, you’ll be able to build high-performing C# applications that deliver a seamless user experience.

Your Go-To Solution for Generating Realistic Indian Data
Jul 17, 2024

In the world of software development and testing, having access to realistic and diverse data sets is crucial. That's why we are thrilled to introduce IndiGen, a powerful and versatile package designed to generate realistic Indian data with ease.   Why IndiGen? IndiGen is a comprehensive tool that caters specifically to the needs of developers and testers who require authentic Indian data for their projects. Whether you are working on unit tests, creating sample data, or validating functionality, IndiGen has got you covered. Key Features Realistic Indian Names: Generate complete names, first names, last names, middle names, prefixes, and suffixes. var fullName = India.Faker.Name.FullName(); // Example: Ramesh Babu var firstName = India.Faker.Name.First(); // Example: Amitabh var lastName = India.Faker.Name.Last(); // Example: Kapoor var middleName = India.Faker.Name.Middle(); // Example: Hrutvik var prefix = India.Faker.Name.Prefix(); // Example: Shri var suffix = India.Faker.Name.Suffix(); // Example: Bhai, Kumar   Valid Phone Numbers: Generate realistic Indian phone numbers. var phoneNumber = India.Faker.Phone.Number(); // Example: +91-9988776655, 9998887770, 079-27474747   Authentic Vehicle Number Plates: Generate vehicle number plates in Indian formats. var vehicleNumberPlate = India.Faker.VehicleNumberPlate.Number(); // Example: GJ 01 AA 7777, 24 BH 9999 AA   Valid PAN Card Numbers: Generate PAN card numbers that conform to Indian standards. var panCardNumber = India.Faker.PanCardNumber.Number(); // Example: AABBB8888A   Aadhaar Card Numbers: Generate Aadhaar card numbers. var aadhaarCardNumber = India.Faker.AadharCardNumber.Number(); // Example: 2222 4444 2222   Supported Versions IndiGen is compatible with a wide range of .NET versions, ensuring flexibility and ease of integration into your projects: .NET Framework 4.5, 4.6, 4.7, 4.8 .NET Standard 2.0, 2.1 .NET Core 3.0, 3.1 .NET 5.0, 6.0 Get Started with IndiGen Getting started with IndiGen is simple. Visit our NuGet package page and integrate it into your projects to start generating realistic Indian data today.   How to Install Installing IndiGen is straightforward. You can add it to your project using the NuGet Package Manager, .NET CLI, or by editing your project file. Using NuGet Package Manager Open your project in Visual Studio. Go to Tools > NuGet Package Manager > Manage NuGet Packages for Solution. Search for IndiGen. Select the package and click Install. Using .NET CLI Run the following command in your terminal:\ dotnet add package IndiGen Editing Your Project File Add the following line to your .csproj file: <PackageReference Include="IndiGen" Version="8.0.1" /> Replace "8.0.1" with the latest version of IndiGen.  NuGet Package: IndiGen   Contribute to IndiGen We welcome contributions from the community. If you have suggestions, improvements, or new features in mind, please open an issue or submit a pull request. Together, we can make IndiGen even better! IndiGen is here to simplify your development and testing process by providing realistic Indian data. Try it out and let us know your thoughts. Happy coding!

Comparison between Minimal APIs and Controllers
Jun 17, 2024

Introduction  In the ever-evolving landscape of web development, simplicity is key. Enter Minimal APIs in ASP.NET Core, a lightweight and streamlined approach to building web applications. In this detailed blog, we'll explore the concept of Minimal APIs, understand why they matter, and walk through their implementation in ASP.NET Core.    When to Use Minimal APIs?  Minimal APIs are well-suited for small to medium-sized projects, microservices, or scenarios where a lightweight and focused API is sufficient. They shine in cases where rapid development and minimal ceremony are top priorities.  You can find in this blog <link> how to create minimal api.  I am directly showing the comparison between MinimalAPI and controller.    Controllers: Structured and Versatile  Controllers, deeply rooted in the MVC pattern, have been a cornerstone of ASP.NET API development for years. They provide a structured way to organize endpoints, models, and business logic within dedicated controller classes.  Let's consider an example using Microsoft.AspNetCore.Mvc; namespace MinimalAPI.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } } } Advantages of Controllers in Action  Structure and Organization: Controllers offer a clear structure, separating concerns and enhancing maintainability.  Flexibility: They enable custom routes, complex request handling, and support various HTTP verbs.  Testing: Controllers facilitate unit testing of individual actions, promoting a test-driven approach   Minimal APIs: Concise and Swift  With the advent of .NET 6, Minimal APIs emerged as a lightweight alternative, aiming to minimize boilerplate code and simplify API creation.  Here's an example showcasing Minimal APIs.  using MinimalAPI; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); app.MapGet("/GetWeatherForecast", () => { var rng = new Random(); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; var weatherForecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index).Date, TemperatureC = rng.Next(-20, 55), Summary = summaries[rng.Next(summaries.Length)] }).ToArray(); return Results.Ok(weatherForecasts); }); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); Advantages of Minimal APIs in Focus  Simplicity: Minimal APIs drastically reduce code complexity, ideal for smaller projects or rapid prototyping.  Ease of Use: They enable quick API creation with fewer dependencies, accelerating development cycles.  Potential Performance Boost: The reduced overhead might lead to improved performance, especially in smaller applications.    What you choose between MinimalAPI and Controller?  Choosing between Controllers and Minimal APIs hinges on various factors.  Project Scale: Controllers offer better organization and structure for larger projects with intricate architectures.  Development Speed: Minimal APIs shine when speed is crucial, suitable for rapid prototyping or smaller projects.  Team Expertise: Consider your team's familiarity with MVC patterns versus readiness to adopt Minimal APIs.    Conclusion  The decision between Controllers and Minimal APIs for .NET APIs isn't about one being superior to the other. Rather, it's about aligning the choice with the project's specific needs and constraints. Controllers offer robustness and versatility, perfect for larger, complex projects. On the other hand, Minimal APIs prioritize simplicity and rapid development, ideal for smaller, more straightforward endeavours. 

Role based Authorization in ASP .NET core
Jun 14, 2024

What is Authorization?  Authorization verifies whether a user has permission to use specific applications or services. While authentication and authorization are distinct processes, authentication must precede authorization, ensuring the user's identity is confirmed before determining their access rights.    When logging into a system, a user must provide credentials like a username and password to authenticate. Next, the authorization process grants rights. For example, an administrative user can create a document library to add, edit, and delete documents, while a non-administrative user can only read documents in the library.  Types of Authorization:  Simple Authorization  Role-Based Authorization  Claim-Based Authorization  Policy-Based Authorization  I have implemented an example of role-based authorization in .NET. Step 1: Create one new MVC Web Application with the Authentication type “Individual Account”.  Step 2: Register Identity with DefaultTokenProvider in the program.cs file. builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = false) .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); For better understanding, I have added one page to add a new role.  Create a new method in the controller and add the following code. [HttpGet] public IActionResult Admin() { return View(); } Create a new model Role.cs.   namespace Authorization.Models { public class Role { public string RoleName { get; set; } } } Create html page for add role.  @model Role @{ ViewData["Title"] = "Admin"; } <h1>Admin</h1> <div class="row"> <div class="col-md-12"> <form method="post" action="@Url.Action("Admin","Home")"> <div class="form-group"> <label>Role Name</label> <input type="text" class="form-control" style="width:30%;" asp-for="RoleName" placeholder="Role name" required> </div> <br /> <button class="btn btn-success" type="submit">Add</button> </form> </div> </div> I have created a simple page, You can modify the page as per your requirements.  Add a new method in the controller and add the following code. And declare RoleManager<IdentityRole> and inject in the constructor. private readonly RoleManager<IdentityRole> _roleManager; public HomeController(RoleManager<IdentityRole> roleManager) { _roleManager = roleManager; } [HttpPost] public async Task<IActionResult> Admin(Role role) { var result = _roleManager.RoleExistsAsync(role.RoleName).Result; if (!result) { await _roleManager.CreateAsync(new IdentityRole(role.RoleName)); } return RedirectToAction("Admin"); } Set a new tab in _Layout.cshtml file to redirect to the Add role page.  <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Admin">Add new role</a> </li> Run the project and you will see the output. Here, You can add a new role.  Add a new field in register.cshtml using the following code to assign a role to the user.  <div class="form-floating mb-3"> <select asp-for="Input.Role" class="form-control" aria-required="true"> <option value="">Select role</option> @foreach (var item in Model.RoleList) { <option value="@item.Name">@item.Name</option> } </select> <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> </div> To get the list of roles you can add the following code in your register.cshtml.cs file. And Add  RoleList = _roleManager.Roles in OnPostAsync method also. public IQueryable<IdentityRole> RoleList { get; set; } public async Task OnGetAsync(string returnUrl = null) { ReturnUrl = returnUrl; RoleList = _roleManager.Roles; ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); } Run the project and see the output. Now, Assign the role to the user, and for that add the following code in OnPostAsync after the user is created. await _userManager.AddToRoleAsync(user, Input.Role); Full code of register.cshtml.cs file. using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.WebUtilities; using System.ComponentModel.DataAnnotations; using System.Text; namespace Authorization.Areas.Identity.Pages.Account { public class RegisterModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; private readonly UserManager<IdentityUser> _userManager; private readonly RoleManager<IdentityRole> _roleManager; private readonly IUserStore<IdentityUser> _userStore; private readonly IUserEmailStore<IdentityUser> _emailStore; private readonly ILogger<RegisterModel> _logger; //private readonly IEmailSender _emailSender; public RegisterModel( UserManager<IdentityUser> userManager, IUserStore<IdentityUser> userStore, SignInManager<IdentityUser> signInManager, ILogger<RegisterModel> logger, RoleManager<IdentityRole> roleManager ) { _userManager = userManager; _userStore = userStore; _emailStore = GetEmailStore(); _signInManager = signInManager; _roleManager = roleManager; _logger = logger; } [BindProperty] public InputModel Input { get; set; } public IQueryable<IdentityRole> RoleList { get; set; } public string ReturnUrl { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } public class InputModel { [Required] [EmailAddress] [Display(Name = "Email")] public string Email { get; set; } [Required] [Display(Name = "Role")] public string Role { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } } public async Task OnGetAsync(string returnUrl = null) { ReturnUrl = returnUrl; RoleList = _roleManager.Roles; ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); RoleList = _roleManager.Roles; ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { var user = CreateUser(); await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); await _userManager.AddToRoleAsync(user, Input.Role); var userId = await _userManager.GetUserIdAsync(user); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); if (_userManager.Options.SignIn.RequireConfirmedAccount) { return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl }); } else { await _signInManager.SignInAsync(user, isPersistent: false); return LocalRedirect(returnUrl); } } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } return Page(); } private IdentityUser CreateUser() { try { return Activator.CreateInstance<IdentityUser>(); } catch { throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityUser)}'. " + $"Ensure that '{nameof(IdentityUser)}' is not an abstract class and has a parameterless constructor, or alternatively " + $"override the register page in /Areas/Identity/Pages/Account/Register.cshtml"); } } private IUserEmailStore<IdentityUser> GetEmailStore() { if (!_userManager.SupportsUserEmail) { throw new NotSupportedException("The default UI requires a user store with email support."); } return (IUserEmailStore<IdentityUser>)_userStore; } } } Now, register one new user and assign a role to them. For example, I have created one user and assign “Admin” to them. I have added two new methods in the controller and added a default view for that.  [Authorize(Roles = "User")] public IActionResult UserRoleCheck() { return View(); } [Authorize(Roles = "Admin")] public IActionResult AdminRoleCheck() { return View(); } I have set the Authorize attribute with the role name on both authorization methods. Now, I am running the project and clicking on Admin Role, It will open the page of admin because the logged user role and method role both are the same.  If I click on User Role, It will give an Access denied error. Because logged user role and method role both are different. Here, I am using by default access denied page of identity. You can use custom page also, Just set this path to program.cs file. builder.Services.ConfigureApplicationCookie(options => { options.AccessDeniedPath = "/Identity/Account/AccessDenied"; // Customize this path as per your application's structure }); Using this way you will implement the role-based authorization in your application. Conclusion  By properly implementing authorization in your applications, you can ensure that resources and sensitive information are accessible only to authorized users. Remember to choose the appropriate authorization technique based on your application’s requirements and complexity.

Dependency Injection with Example
Jun 12, 2024

What is the Dependency Injection Design Pattern? Dependency Injection is a design pattern used to execute Inversion of control (IoC). It is a process of injecting the dependency object into a class that depends on it. Dependency Injection is the often-used design pattern these days to separate the dependencies between the objects that allow us to implement loosely coupled software components. It allows the making of dependent objects outside of the class and supplies those objects to a class in distinct ways. Let’s talk about the bit-by-bit process to implement dependency Injection in the ASP.Net Core application. The ASP.NET Core Framework provides inbuilt support for Dependency Injection design patterns. It injects the dependency objects to a class via a constructor, method, or property using the built-in IoC container. The inbuilt IoC container is elected by IServiceProvider implementation, which supports default construction injection. The classes managed by built-in IoC Containers are called services.   Types of Services in ASP.NET Core There are 2 types of services in ASP.NET core. Framework Services: Services that are a part of the ASP.NET core framework, like IApplicationBuilder, IHostingEnvironment, ILoggerFactory, etc. Application Services: The services you create as a programmer for your application. Before registering services, let’s first know the different methods to register a service. The ASP.NET core gives 3 methods to register a service with a Dependency Injection container. The method that we use to register a service will determine the lifetime of the service. Singleton: A Singleton service is created only once per application lifetime. The same instance is used all over the application. Common uses contain configuration services, logging, or other services where a single instance is enough and advisable. Since the same instance is used throughout, you need to ensure that Singleton services are thread-safe. Not suitable for saving user-specific data or request-specific data. This can be reached by adding the service as a singleton through the AddSingleton method of the IServiceCollection. Transient: A Transient service is created every time it is requested from the service container. This means that a new instance is provided to every class or method that requires it. Suitable for lightweight, stateless services. Since a new instance is created every time, you don’t need to worry about thread safety related to the internal state. While transient services are simple and provide clean separation, they can be more resource-intensive if they are vast or require significant resources to build. This can be got by adding the service through the AddTransient method of the IServiceCollection. Scoped: A scoped service is created once per client request (means per HTTP request). Perfect for services that need to maintain state within a single request but should not be shared across different requests. This can be achieved by adding the service through the AddScoped method of the IServiceCollection.   How to Register a Service with ASP.NET Core Dependency Injection Container? We need to register a service to the in-built dependency injection container with the program class.  The below code shows how to register a service with different lifetimes. var builder = WebApplication.CreateBuilder(args); // ADD FRAMEWORK MVC SERVICES TO THE CONTAINER builder.Services.AddMvc(); // ADD APPLICATION SERVICES TO THE CONTAINER builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA())); // BY DEFAULT SINGLETON builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA(),ServiceLifetime.Singleton)); // SINGLETON builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA(),ServiceLifetime.Transient)); // TRANSIENT builder.Services.Add(new ServiceDescriptor(typeof(ISubjectTypesDA), new SubjectTypesDA(),ServiceLifetime.Scoped)); // SCOPED   What is the ServiceDescriptor class in .NET Core? This class speaks for a descriptor of a service in the DI Container. It essentially describes how to service should be instantiated and managed by the container. So, it describes a service, including its lifetime, the service type, and the implementation type. Extension methods for Registration ASP.NET Core framework contains extension methods for each type of lifetime: AddSingleton, AddTransient, and AddScoped methods.  The below example shows how to register types of lifetimes using extension methods. // ADD APPLICATION SERVICE TO THE CONTAINER. services.AddTransient<IEmailSenderBL, EmailSenderBL>(); // TRANSIENT services.AddScoped<ISubjectTypesBL, SubjectTypesBL>(); // SCOPED services.AddSingleton<ICPCalculationBL, CPCalculationBL>(); // SINGLETON   The dependent class is a class which depends on the dependency class. The dependency class is a class that provides service to the dependent class. The interface injects the dependency class object into the dependent class.   There are 3 types of Dependency Injection. Constructor Injection Property Injection Method Injection   Constructor Injection: we register the service, the IoC automatically executes constructor injection if a service type is included as a parameter in a constructor. Example: public class CenterController : BaseController { private ICenterBL _centerBL; public CenterController(ICenterBL centerBL) : base(myLoginUser) { _centerBL = centerBL; } [Authorize] public IActionResult Index() { try { var data = _centerBL.GetCenterpageList(); return View(data); } catch (Exception EX) { throw EX; } } }   Property Injection: Not required to add dependency services in the constructor. We can manually access the services configured with built-in IoC containers using the RequestServices property of HttpContext.   public class AddressController : Controller { [Authorize] public IActionResult Index() { var services = this.HttpContext.RequestServices; IAddressBL _address = (IAddressBL)services.GetService(typeof(IAddressBL)); var data = _address.GetAddressList(); return View(data); } }   Method Injection: Occasionally, we may only need a dependency object in a single action method. In that case, we need to use the [FromServices] attribute with the service type parameter in the action method. In the below example, you can see we are using the [FromServices] attribute within the Index action method. So, at runtime, the IoC Container will inject the dependency object to the IAddressBL repository reference variable. As we inject the dependency object through a method, it is called method dependency injection. public class CommonController: Controller { public IActionResult Index([FromServices] IAddressBL _addressBL) { var list = _addressBL.GetAddressList(); return View(list); } } Advantages of Dependency Injection Loose Coupling: we can separate our classes from their dependencies. This results in code that is simpler to maintain and test. Testability: we can increase the testability of our code since we can easily replace dependencies with mock objects during unit testing. Extensibility: enhance the extensibility of our code by offering the flexibility to switch out dependencies conveniently. Reusability: makes our code more reusable since we can conveniently share dependencies among various classes.  

How to create MinimalAPI in .NET
May 27, 2024

What is MinimalAPI?  Minimal APIs are a simplified way of building web APIs in ASP.NET Core. They are designed for scenarios where you need a quick and minimalistic approach to expose endpoints without the overhead of a full-fledged MVC application.    Why Minimal APIs?  Efficiency: Write less, do more. A mantra for the modern developer.  Performance: They’re lean, mean, and fast, perfect for high-performance scenarios.  Ease of Use: New to .NET? No problem! Minimal APIs are accessible and easy to grasp.  Flexibility: Simplicity doesn’t mean limited. From microservices to large-scale applications, they’ve got you covered.    How Minimal APIs Work?  Minimal APIs leverage the WebApplication class to define routes and handle HTTP requests. They rely on a functional approach, allowing developers to define endpoints using lambda expressions.    Limitations of Minimal API  No support for filters: For example, no support for IAsyncAuthorizationFilter, IAsyncActionFilter, IAsyncExceptionFilter, IAsyncResultFilter, and IAsyncResourceFilter.  No support for model binding, i.e. IModelBinderProvider, IModelBinder. Support can be added with a custom binding shim.  No support for binding from forms. This includes binding IFormFile. We plan to add support for IFormFile in the future.  No built-in support for validation, i.e. IModelValidator  No support for application parts or the application model. There's no way to apply or build your own conventions.  No built-in view rendering support. We recommend using Razor Pages for rendering views.  No support for JsonPatch  No support for OData    How to create a Minimal API?  Creating a Minimal API closely mirrors the traditional approach, so you should encounter no significant challenges. It is a straightforward procedure that can be accomplished in just a few easy steps.  Let's get started:  Step 1:   Open Visual Studio and select the ASP.NET Core Web API.  Provide a preferred name for your project and select the location where you wish to store it.  For the final step, choose the targeted framework, ensure that the "Configure for HTTPS" and "Enable OpenAPI support" checkboxes are checked, and, most importantly, leave the checkbox "Use controllers (uncheck to use Minimal API)" unchecked. Then, click the "Create" button.  Step 2:  Create one class with two fields and create one list class with some static values.  namespace MinimalAPI { public class Student { public int Id { get; init; } public string Name { get; set; } } public static class StudentList { public static List<Student> student = new List<Student>() { new Student() { Id = 1, Name = "Test1", }, new Student() { Id = 2, Name = "Test2", }, new Student() { Id = 3, Name = "Test3", } }; } } Now add register new endpoint in Program.cs file.  app.MapGet("GetAllStudent", () => StudentList.student); Run the project and see the output.  I have added Create, Update and Delete student endpoint. See the full code below.  using MinimalAPI; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // GetAll app.MapGet("GetAllStudent", () => StudentList.student); // GetById app.MapGet("GetByStudentId/{id}", (int id) => StudentList.student.FirstOrDefault(user => user.Id == id)); // Create app.MapPost("CreateStudent", (Student student) => StudentList.student.Add(student)); // Update app.MapPut("UpdateStudent/{id}", (int id, Student student) => { Student currentStudent = StudentList.student.FirstOrDefault(user => user.Id == id); currentStudent.Name = student.Name; }); // Delete app.MapDelete("DeleteStudent/{id}", (int id) => { var student = StudentList.student.FirstOrDefault(user => user.Id == id); StudentList.student.Remove(student!); }); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); Run the code and see the output. Conclusion:  Minimal APIs in ASP.NET Core, introduced in .NET 6, offer a simplified and concise approach to building lightweight HTTP services, reducing boilerplate and emphasizing convention-based routing. While ideal for rapid development of small to medium-sized APIs, they lack advanced features found in traditional ASP.NET Core applications and may not be suitable for complex scenarios. 

Easy Guide to Cancellation Tokens in .NET
Jan 31, 2024

In this blog I'll show how you can use a CancellationToken in your ASP.NET Core action method to stop execution when a user cancels a request from their browser. This can be useful if you have long running requests that you don't want to continue using up resources when a user clicks "stop" or "refresh" in their browser. What is Cancellation Token in c#?  Cancellation tokens in C# are used to signal that a task or operation should be cancelled. They allow for the cooperative cancellation of a task or operation, rather than aborting it forcibly.  Why Use Cancellation Tokens? Here are some benefits of using cancellation tokens:  Avoid resource leaks by freeing up un-managed resources linked to the task  Stop further processing when a task is no longer needed  Improve responsiveness by quickly responding to cancellations  Easy propagation of cancel requests in child tasks  Without cancellation logic, long-running tasks will continue processing in the background even if no longer needed.  You can use cancellaiontoken in any action method or project. Here I am taking one example of .NET web API.  Here, I have created a web API project in .NET, and the above image shows the default controller for the web API, which includes the WeatherForecastController. In that, I have added some log information and added one 10-second task delay that means when this line is executed it will wait for 10 seconds after the next line is executed.  I have added task delay because it is better to understand CancellationToken.  If we hit the URL /GetWeatherForecast then the request will run for 10s, and eventually will return the message. So now, what happens if the user refreshes the browser, halfway through the request? The browser never receives the response from the first request, but as you can see from the logs, the action method executes to completion twice - once for the first (canceled) request, and once for the second (refresh) request.  Whether this is correct behavior will depend on your application.    ASP.NET Core provides a mechanism for the webserver to signal when a request has been canceled using a CancellationToken. This is exposed as HttpContext.RequestAborted, but you can also inject it automatically into your actions using model binding.  Using CancellationToken in your method  CancellationTokens are lightweight objects that are created by a CancellationTokenSource. When a CancellationTokenSource is cancelled, it notifies all the consumers of the CancellationToken. This allows one central location to notify all of the code paths in your app that cancellation was requested.  When cancelled, the IsCancellationRequested property of the cancellation token will be set to True, to indicate that the CancellationTokenSource has been cancelled.  Lets consider the previous example again. We have a long-running action method . As it as an expensive method, we want to stop executing the action as soon as possible if the request is cancelled by the user.  The following code shows how we can hook into the central CancellationTokenSource for the request, by injecting a CancellationToken into the action method, and passing the parameter to the Task.Delay call.  MVC will automatically bind any CancellationToken parameters in an action method to the HttpContext.RequestAborted token, using the CancellationTokenModelBinder.    This model binder is registered automatically when you call services.AddMvc() (or services.AddMvcCore()) in Startup.ConfigureServices().  With this small change, we can test out our scenario again. We'll make an initial request, which starts the long-running action, and then we'll reload the page. As you can see from the logs below, the first request never completes. Instead the Task.Delay call throws a TaskCancelledException when it detects that the CancellationToken.IsCancellationRequested property is true, immediately halting execution.  Summary Users can cancel requests to your web app at any point, by hitting the stop or reload button on your browser. Typically, your app will continue to generate a response anyway, even though Kestrel won't send it to the user. If you have a long-running action method, then you may want to detect when a request is canceled, and stop execution.  You can do this by injecting a CancellationToken into your action method, which will be automatically bound to the HttpContext.RequestAborted token for the request. You can check this token for cancellation as usual, and pass it to any asynchronous methods that support it. If the request is canceled, an OperationCanceledException or TaskCanceledException will be thrown. 

Hosting a .NET Application on IIS Server
Jan 29, 2024

Hosting your .NET application on an IIS (Internet Information Services) server allows it to be accessed and consumed over the internet by users. IIS is commonly used to host .NET applications and web APIs.  Before you can host the application, ensure you have the following:  A .NET web application or API built (for example using ASP.NET Core)  A Windows Server machine with IIS installed and configured  Permissions to remotely access the server over a network    Follow this step-by-step guide to deploy your .NET Application on the IIS Server seamlessly.  Step 1: Open your .NET Application in Visual Studio  Open your application or project in Visual Studio and build the application.    Step 2 : Publish the Application or project.  Now, Right-click on your project and select the publish option.  Here, select the folder and then click on next, and finish the publish setup.  Now, Click on the publish button to publish your code to one folder.  After, publishing is succeeded click on the open folder. You will see your published code in this folder.    Step 3: Configure IIS on the Server  Carry out these steps to prepare IIS for hosting the application. If IIS is not installed in your system, then first install the IIS on your machine.  Open IIS Manager on the Windows Server  Right-click on the Sites folder and click Add Website                    3. Provide a name for the website, Set the physical path to the app folder, and select a port where you want to host the application.                    4. Click OK to create the new IIS website.   Step 4: Publish code to IIS Server.  Now stop the website and open the folder that you have given in the Physical path while configuring it, by right-clicking on your website and selecting explore.  Now, copy all the published files into your server folder.  Once all the files are copied into the publish folder Start the website and click on Browse*: {Your port} (http) under browse website.  you will see the output of your code on the server.  If your project is based on MVC then Recycle Application pool is required. You can find your Application pool under the Application Pool section. Right-click on your website app pool and click on recycle. Conclusion: Hosting the application on IIS allows it to be reached by users from over the network and the internet. It handles request routing and security layers for serving the application.

Quick Tips: Managing Expired Tokens
Jan 01, 2024

Here, I will explain how to restrict users from using expired tokens in a .NET Core application. Token expiration checks are crucial for ensuring the security of your application.   Here's a general outline of how you can achieve this: 1. Configure Token Expiration: When generating a token, such as a JWT, set an expiration time for the token. This is typically done during token creation. For example, when using JWTs, you can specify the expiration claim:   var tokenDescriptor = new SecurityTokenDescriptor {     Expires = DateTime.Now.AddMinutes(30) // Set expiration time }; 2. Token Validation Middleware: Create middleware in your application to validate the token on each request. This middleware should verify the token's expiration time. You can configure this middleware in the startup or program file on the .NET side.   public void Configure(IApplicationBuilder app, IHostingEnvironment env) {     app.UseMiddleware<TokenExpirationMiddleware>(); } 3. Token Expiration Middleware: Develop middleware to validate the token's expiration time. Take note of the following points: ValidateIssuerSigningKey: Set to true, indicating that the system should validate the issuer signing key. IssuerSigningKey: The byte array represents the secret key used for both signing and verifying the JWT token. ValidateIssuer and ValidateAudience: Set to false, indicating that validation of the issuer and audience is skipped. By setting ClockSkew to TimeSpan.Zero, you specify no tolerance for clock differences. If the current time on the server or client is not precisely within the token's validity period, the token is considered expired.      public class TokenExpirationMiddleware     {         private readonly RequestDelegate _next;         public TokenExpirationMiddleware(RequestDelegate next)         {             _next = next;         }         public async Task Invoke(HttpContext context)         {             // Check if the request has a valid token             var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();             if (token != null)             {                 var tokenHandler = new JwtSecurityTokenHandler();                 var key = Encoding.ASCII.GetBytes("YourSecretKey"); // Replace with your actual secret key of Issuer                 var tokenValidationParameters = new TokenValidationParameters                 {                     ValidateIssuerSigningKey = true,                     IssuerSigningKey = new SymmetricSecurityKey(key),                     ValidateIssuer = false,                     ValidateAudience = false,                     ClockSkew = TimeSpan.Zero                 };                 try                 {                     // Validate the token                     var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out var securityToken);                     // Check if the token is expired                     if (securityToken is JwtSecurityToken jwtSecurityToken)                     {                         if (jwtSecurityToken.ValidTo < DateTime.Now)                         {                             // Token is expired                             context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;                             return;                         }                     }                 }                 catch (SecurityTokenException)                 {                     // Token validation failed                     context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;                     return;                 }             }             await _next(context);         }     } Working fine with proper token time. Here is an example: I am providing an expired token, and it will result in a 401 Unauthorized status. You can also check the token in https://jwt.io/ for time expired (exp) . By following these steps, you can effectively implement checks to ensure that users are not able to use expired tokens within your .NET Core application.

magnusminds website loader