The software development industry is rapidly changing, with key trends shaping the landscape in 2024. Staying informed on these trends is important for professionals and businesses to stay competitive and adapt to technological advancements. Despite financial pressures from inflation, businesses continue to invest in digital transformation initiatives to drive growth and efficiency. In our blog, we explore the top 9 software development trends in 2024, from AI advancements to emerging technologies. Native app development is being replaced by progressive web apps, and low code and no code platforms are gaining popularity. Technologies like IoT, augmented reality, blockchain, and AI are leading the way in software advancements. Stay updated with MagnusMinds blogs to learn about generative AI, quantum computing, and other industry innovations. Keep up with the latest trends in software development to stay ahead in the market. Discover how custom software development can benefit companies and explore upcoming industry developments. Stay informed and explore the top software industry trends for 2024. Generative AI Transforms Development Practices Generative AI, such as OpenAI's GPT-4, is transforming modern IT development by revolutionizing code generation, debugging, and design. It is no longer just limited to chatbots but has become an essential tool for enhancing development processes. These advanced models are enhancing natural language processing, automating repetitive tasks, creating complex algorithms, and even generating codebases from simple descriptions. With the integration of generative AI into everyday development tasks, developers can streamline workflows, focus on higher-level problem-solving, and make significant strides in the field of IT development. OpenAI's GPT-4 and similar technologies are at the forefront of this AI-powered development revolution. Example: GitHub Copilot, powered by GPT-4, speeds up development by suggesting code snippets and automating repetitive tasks. For example, a developer writing a Python script for data analysis can use Copilot to create complex functions or handle API integrations with minimal manual effort. Tools like Copilot are changing how code is written, as it can suggest entire functions or snippets based on the code context. This feature expedites development, reduces coding errors, and allows developers to focus on high-level design. OpenAI's Codex is another powerful tool that translates natural language descriptions into code, making it easier to create web forms and other applications quickly. Quantum Computing: Practical Implications on the Horizon Quantum computing is advancing rapidly, promising to revolutionize problem-solving methods across industries. While widespread use of full-scale quantum computers is not yet common, progress is evident in quantum algorithms and hybrid models. The year 2024 is expected to bring significant advancements in quantum computing, with practical applications becoming more prominent. Developers will need to learn quantum programming languages to stay ahead of developments. Despite still being experimental, quantum computing is beginning to make a tangible impact in fields such as cryptography and simulations. Transitioning from theoretical research to practical use, quantum computing is on the brink of major breakthroughs. Example: IBM’s Quantum Hummingbird is a 127-qubit processor pioneering practical quantum computing for drug discovery and material science. By simulating molecular interactions at a quantum level, breakthroughs in creating new pharmaceuticals or materials are on the horizon. On the other hand, D-Wave’s Advantage, a quantum annealing system, is being utilized by companies like Volkswagen to optimize traffic flow in urban areas. Leveraging quantum computing to process complex traffic patterns, Volkswagen aims to enhance city traffic management and overall transportation efficiency. Cybersecurity: Advanced Threat Detection and Response Cybersecurity is a top priority in IT development due to the growing sophistication of cyber threats. In 2024, we expect to see more emphasis on advanced threat detection, zero-trust security models, and comprehensive encryption techniques. Companies are investing in AI-powered systems for detecting threats, while developers are integrating robust security measures and staying informed about the latest practices and compliance requirements. With cyber threats constantly evolving, cybersecurity measures are also advancing to keep up. Regulatory compliance will drive the need for stronger security measures across all development levels to protect against these threats. Example: Google's BeyondCorp is a zero-trust security model that eliminates traditional perimeter-based security measures by continuously verifying user and device identity before granting access. This approach improves security by considering threats from both inside and outside the organization. Meanwhile, Darktrace's Antigena is an autonomous response technology using machine learning to detect and respond to cybersecurity threats in real-time. For example, it can identify unauthorized network activity and promptly act, like isolating affected systems, to prevent further damage. Edge Computing Enhances Real-Time Data Processing Edge computing is gaining traction by moving computational power closer to data sources, reducing latency and improving real-time processing. It is essential for applications needing fast data processing by shortening data travel distance. This technology enhances performance for IoT, autonomous vehicles, and smart cities. To adapt to this shift, developers should focus on optimizing software for edge environments and efficiently managing distributed data. Edge computing is transforming data processing by bringing computation closer to the source, benefiting applications that require real-time data processing. As more companies embrace this trend, developers must optimize applications for decentralized environments and manage data across distributed systems effectively. Example: Edge computing is used in smart cities to analyze data from surveillance cameras in real-time, enabling quick responses to traffic violations or security threats. For example, Cisco's Edge Intelligence platform helps businesses deploy edge computing solutions for real-time analysis of data from IoT sensors, such as predicting equipment failures in manufacturing settings to prevent downtime and improve efficiency. Low-Code and No-Code Platforms Foster Rapid Development Low-code and no-code platforms are revolutionizing application development, allowing non-developers to easily create functional software. These platforms are democratizing the process, empowering users with limited coding skills to build their own applications. As we look ahead to 2024, these platforms will continue to evolve, offering more advanced features and integrations. This advancement will streamline development processes and enable a wider range of individuals to contribute to IT solutions. Developers may increasingly collaborate with these platforms to enhance their capabilities and create tailored solutions for businesses. Example: Low-code/no-code platforms like Microsoft PowerApps, Bubble, and AppGyver empower business users to create custom applications without advanced programming skills. For instance, PowerApps and Bubble enable a marketing team to develop a tailored CRM solution without IT support. AppGyver offers a no-code environment for building complex mobile and web apps, such as a healthcare provider designing a custom patient management system for better service delivery and streamlined information handling. check full details about PowerApps in our Detailed Guide. Green IT: Driving Sustainable Practices Sustainability is becoming a key priority in IT development, with a particular emphasis on green IT practices to reduce environmental impact. This includes energy-efficient data centers, sustainable hardware, and eco-friendly coding techniques gaining popularity. Companies are placing a greater importance on incorporating sustainability into their IT strategies to decrease their carbon footprint and uphold environmental responsibility. As a result, developers are being urged to consider the ecological implications of their work and integrate sustainable practices into their projects. This shift towards green IT is essential for minimizing environmental impact and promoting eco-friendly operations in the IT industry. Example: Tech giants like Google and Microsoft are leading the way in adopting energy-efficient technologies in data centers. Google has committed to operating all data centers on renewable energy, setting a high standard for the industry. Microsoft's Project Natick is developing underwater data centers that use natural cooling properties, reducing energy consumption. These efforts are reducing carbon footprints and creating a more sustainable IT infrastructure. 5G and Emerging 6G Technologies The roll out of 5G networks is boosting connectivity, speeding up data transfer, and introducing new applications. Research is already in progress for 6G technology, which is expected to bring further advancements. In 2024, we can anticipate significant progress in 5G technology and exploration of 6G possibilities. These advancements will fuel innovation in augmented reality (AR), virtual reality (VR), and the Internet of Things (IoT). The expansion of 5G networks is revolutionizing connectivity by supporting fast data speeds and reducing latency. This year, we are witnessing wider acceptance of 5G, driving innovations in AR, VR, and IoT. Additionally, ongoing research into 6G technology is likely to lead to even more advanced connectivity solutions. Developers should stay informed about these developments to harness new opportunities and create applications that can fully utilize next-generation networks. Example: The deployment of 5G networks has led to the rise of real-time interactive augmented reality (AR) applications like gaming and remote assistance. Researchers are now looking into 6G technology to achieve even faster speeds and lower latency, potentially transforming fields like autonomous driving and immersive virtual reality experiences. Additionally, Qualcomm's Snapdragon X65 5G modem allows for high-speed data transfer and low latency, enabling applications such as high-definition live streaming and AR experiences. The development of 6G may further advance technologies like holographic communication and immersive VR environments. Enhanced User Experience (UX) with AI and Personalization User experience (UX) is vital, focusing on personalized and intuitive interfaces. The evolution of UX emphasizes personalization and intelligent design, aided by AI advancements. In 2024, IT development will prioritize creating personalized experiences across digital platforms. AI-driven insights will enable developers to customize applications and services based on individual user preferences and behaviors. Enhancing engagement and satisfaction, developers are increasingly tailoring experiences to user preferences. UX design is becoming more data-driven, emphasizing understanding user behavior to create meaningful interactions. Exceptional user experiences, focusing on personalization, remain a top priority in the industry. Example: Streaming services like Netflix utilize machine learning algorithms to analyze user preferences and habits, offering personalized content recommendations for an improved user experience. Similarly, Adobe Experience Cloud employs AI technology to personalize content and optimize user experiences on various platforms, enhancing user engagement and satisfaction through tailored recommendations and targeted marketing strategies. Blockchain Applications Beyond Financial Transactions Blockchain technology is expanding beyond cryptocurrency into various industries. By 2024, it will be prominently used in supply chain management, identity verification, and smart contracts. The transparency and security features of blockchain make it a valuable tool for businesses. Streaming services like Netflix utilize machine learning to analyze user habits and provide personalized content recommendations, improving user satisfaction. This personalized approach ensures that the content offered matches individual preferences and viewing history. Blockchain developers need to understand its principles and explore its potential in different scenarios outside of financial transactions. Example: Blockchain is utilized in supply chain management to trace product origins, enhance transparency, and mitigate fraud. IBM and Walmart employ blockchain to monitor goods from production to consumption, improving food safety. Everledger, on the other hand, utilizes blockchain to track diamonds and high-value items, creating an unchangeable record of their journey. This ensures transparency and helps in preventing fraud within the diamond supply chain, offering consumers accurate information regarding their purchases. Advancements in Remote Work and Collaboration Tools The remote work trend is advancing with upgraded tools for collaboration and project management. Companies are investing in enhanced tools for productivity and teamwork. Developers are creating more integrated, secure, and efficient solutions like virtual workspaces, collaborative coding environments, and project management tools. The goal is to design solutions that enable seamless communication and productivity, regardless of location. Example: The remote work trend is growing with improved collaboration and project management tools. Companies are investing in productivity and teamwork tools. Developers are creating secure, efficient solutions like virtual workspaces and collaborative coding environments to enhance communication and productivity. Conclusion The software development landscape in 2024 is characterized by rapid advancements and transformative technologies such as generative AI, edge computing, cybersecurity, and sustainability. Staying informed about these trends is crucial for IT professionals and organizations to leverage new technologies effectively and remain competitive in a rapidly evolving industry. Adapting to these changes will be key for developers to push the boundaries of what's possible and shape the future of IT. By embracing innovations like generative AI, quantum computing, and advanced cybersecurity, the industry is presented with new opportunities for growth and progress. Keeping an eye on these trends throughout the year will ensure that you stay current and position yourself for future success. Stay tuned for more insights and updates as we navigate these exciting developments together.
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.
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!
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.
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.
To utilize custom fonts from your Dotnet codebase in HTML or PDF documents, follow these steps: Add the fonts you intend to use for your PDF or HTML documents. Ensure they are in the .ttf extension format. <PackageReference Include="Polybioz.HtmlRenderer.PdfSharp.Core" Version="1.0.0"> Include the necessary package by adding the following line to your project file: Initialize the IServiceCollection to utilize the CustomFontResolver class. You can achieve this by adding the following extension method: public static class IServicesCollectionExtension { public static IServiceCollection InitializeDocumentProcessor(this IServiceCollection services) { GlobalFontSettings.FontResolver = new CustomFontResolver(); return services; } } Initialize the class in your program file: builder.Services.InitializeDocumentProcessor(); Specify the DefaultFontName you wish to use. You can also manage bold and italic styles. public class CustomFontResolver : IFontResolver { string IFontResolver.DefaultFontName => "Rubik"; public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic) { if (isBold) { if (isItalic) { return new FontResolverInfo("Rubik#bi"); } return new FontResolverInfo("Rubik#b"); } if (isItalic) return new FontResolverInfo("Rubik#i"); return new FontResolverInfo("Rubik"); } public byte[] GetFont(string faceName) { switch (faceName) { case "Rubik": return CustomFontHelper.Rubik; case "Rubik#b": return CustomFontHelper.RubikBold; case "Rubik#bi": return CustomFontHelper.RubikBoldItalic; case "Rubik#i": return CustomFontHelper.RubikItalic; } return GetFont(faceName); } } Define a helper class CustomFontHelper to facilitate loading font data. Ensure you have added the fonts for all the types you intend to use. public static class CustomFontHelper { public static byte[] Rubik { get { return LoadFontData("Rubik-Light.ttf"); } } public static byte[] RubikBold { get { return LoadFontData("Rubik-SemiBold.ttf"); } } public static byte[] RubikBoldItalic { get { return LoadFontData("Rubik-SemiBoldItalic.ttf"); } } public static byte[] RubikItalic { get { return LoadFontData("Rubik-Italic.ttf"); } } static byte[] LoadFontData(string name) { using (Stream stream = File.OpenRead("Fonts/" + name)) { if (stream == null) throw new ArgumentException("No resource with name " + name); int count = (int)stream.Length; byte[] data = new byte[count]; stream.Read(data, 0, count); return data; } } } By following these steps, you can seamlessly integrate custom fonts into your HTML and PDF documents from your Dotnet codebase, without needing to specify the font-family in the HTML directly. You can also pass font styles directly through code.
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.
What is Authentication? Authentication is the process of validating the identity of a user or system attempting to access a protected resource. In C# programming, authentication is commonly implemented in various scenarios, including web applications, desktop applications, and services. Types of Authentications Basic Authentication Password-based Authentication Multi-Factor Authentication Token-based Authentication Let’s understand authentication with example. Here I am taking one example of MFA (Two-factor authentication). Step 1: Create the MVC Web Application Open Visual Studio and select File >> New >> Project. After selecting the project, a “New Project” dialog will open. Select ASP.NET Core web app (Model-View-Controller) and press Next and enter project name and click Next. Choose 'Individual Account' as the authentication type and click 'Create' to generate the project. Step 2: Adding QR Codes to configure two-factor authentication We will be using a QR code to configure and sync the Google authenticator app with our web app. Download the qrcode.js JavaScript library from https://davidshimjs.github.io/qrcodejs/ and put it into the “wwwroot\lib” folder in your application. Now, your “wwwroot” folder will have the following structure. Now, Add new scaffolded item in your project by right click on Area folder and select New scaffolded Item under Add section. Select Identity section on left sidebar and click on Add. Now, Select the identity files that you have to add to your project but select file “Account/Manage/EnableAuthenticator” is compulsory for 2FA. Select the DbContext Class of your project and click on add. Open the “Views\Manage\EnableAuthenticator.cshtml” file. You will find @section Scripts at the end of the file. Put the following code in it. @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") <script src="~/lib/qrcode/qrcode.js"></script> <script type="text/javascript"> new QRCode(document.getElementById("qrCode"), { text: "@Html.Raw(Model.AuthenticatorUri)", width: 200, height: 200 }); </script> } Note: Change your script path as per your folder structure. This “EnableAuthenticator.cshtml” file already has a div with the id “qrCode” (see the code snippet below). We are generating a QR code inside that div using the qrcode.js library. We are also defining the dimensions of the QR code in terms of width and height. So finally, your “EnableAuthenticator.cshtml” file will look like this. @page @model EnableAuthenticatorModel @{ ViewData["Title"] = "Configure authenticator app"; ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication; } <partial name="_StatusMessage" for="StatusMessage" /> <h3>@ViewData["Title"]</h3> <div> <p>To use an authenticator app go through the following steps:</p> <ol class="list"> <li> <p> Download a two-factor authenticator app like Microsoft Authenticator for <a href="https://go.microsoft.com/fwlink/?Linkid=825072">Android</a> and <a href="https://go.microsoft.com/fwlink/?Linkid=825073">iOS</a> or Google Authenticator for <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en">Android</a> and <a href="https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8">iOS</a>. </p> </li> <li> <p>Scan the QR Code or enter this key <kbd>@Model.SharedKey</kbd> into your two factor authenticator app. Spaces and casing do not matter.</p> <div class="alert alert-info">Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable QR code generation</a>.</div> <div id="qrCode"></div> <div id="qrCodeData" data-url="@Model.AuthenticatorUri"></div> </li> <li> <p> Once you have scanned the QR code or input the key above, your two factor authentication app will provide you with a unique code. Enter the code in the confirmation box below. </p> <div class="row"> <div class="col-md-6"> <form id="send-code" method="post"> <div class="form-floating mb-3"> <input asp-for="Input.Code" class="form-control" autocomplete="off" placeholder="Please enter the code."/> <label asp-for="Input.Code" class="control-label form-label">Verification Code</label> <span asp-validation-for="Input.Code" class="text-danger"></span> </div> <button type="submit" class="w-100 btn btn-lg btn-primary">Verify</button> <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div> </form> </div> </div> </li> </ol> </div> @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") <script src="~/lib/qrcode/qrcode.js"></script> <script type="text/javascript"> new QRCode(document.getElementById("qrCode"), { text: "@Html.Raw(Model.AuthenticatorUri)", width: 200, height: 200 }); </script> } When we execute the program, a QR code will be generated in this View. Then you can set up two factor authentication using the Google authenticator with the help of this QR code. Step 3: Configure two-factor authentication Before running the application, we need to apply migrations to our app. Navigate to Tools >> NuGet Package Manager >> Package Manager Console. It will open the Package Manager Console. Put in the “Update-Database” command and hit Enter. This will update the database using Entity Framework Code First Migrations. Run the application and click on “Register” in the top right corner of the homepage. You can see a user registration page. Fill in the details and click on the “Register” button as shown in the image below. Upon successful registration, you will be logged into the application and navigated to the home page. Here, you can see your registered Email id at the top right corner of the page. Click on it to navigate to the “Manage your account” page. Select “TwoFactorAuthentication” from the left menu. You will see a page similar to that shown below. Click on the “Set up authenticator app” button. You can see a QR code generated on your screen — it is asking for a “Verification Code”, also as shown in the image below. You need to install the Google Authenticator/Microsoft Authenticator app on your smartphone. It will allow you to scan this QR code in order to generate a Verification Code and complete a two-factor authentication setup. Open Microsoft Authenticator and click on verified IDs at the bottom. Click on “Scan a barcode” and scan the QR code generated by the web app. This will add a new account to Microsoft authenticator and generate a six-digit pin on your mobile screen. This is our two-factor authentication code. This is a TOTP ( time-based one-time password). You can observe that it keeps on changing frequently (life span of 30 seconds). Put this pin in the Verification Code textbox and click on verify. Upon successful verification, you will see a screen similar to the one shown below. This will give you the recovery codes for your account that will help to recover your account in case you are locked out. Take a note of these codes and keep them somewhere safe. Logout of the application and click on login again. Enter your registered email id and password and click on login. Now you can see a the two-factor authentication screen asking for the Authenticator code. Put in the code that is generated in your Google Authenticator app and click on Login. You will be successfully logged into the application and navigated to the home page.
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.