Pioneer in Offering CRM Solutions since 2010...
Need Help ?
icon

Project Overview

Client already has an running application. Web API was developed in .NET framework 4.5 and front end is developed in Angular. Mobile Apps are developed using Flutter. They are strictly following encryption guidelines of NPCI. Client is strongly preferring Microsoft Azure Services over any other. They are already using various Azure Services like Database is Azure SQL, Azure Repository as code repository, Azure DevOps as DevOps tool, etc.

challenge-vector

Challenges

As client is involved into the FinTech industry, performance and security is the prime concern from their end, also they have their own various challenges:

  • They wanted to migrate from .NET framework to .NET 6. As there are drastic changes / improvements done in .NET 6, faced following challenges into the same:
    • Convert code base to use the dependency injection.
    • Migrate Entity framework Database first to the EF core
    • Microsoft removed the System.Web namespace completely from .NET Core and later versions, need to migrate / find alternative code where we used code dependencies of System.
    • Everywhere as needed basis values from the web.config is fetched using ConfigurationManager class even inside the class library.
    • No centralized exception handling mechanism. Everywhere, try and catch blocks written to handle such exceptions.
    • No API throttling mechanism implemented.
    • Logs are in the files. No automated log tracking mechanism implemented.
    • Secrets are maintained into the web.config file which is pushed through the code base.
    • Lack of using Inheritance properly. Means many models have some common properties and different operations performed on those properties are replicated multiple times.
    • There is no centralized way to call specific API. for each call, they wrote an independent call.
    • There are many different-different model specific filters which do the similar type of job.
    • Migration of Microsoft.Azure.ServiceBus to Azure.Messaging.ServiceBus using .NET 6
    • They wanted to conditionally control to use the Azure Service Bus and self hosted RabbitMQ instance.
    • Migration from Newtonsoft.Json to system.text.json and deal with polymorphic deserialization errors and deal with issues related to null values and case sensitive type checking
challenge-vector

Solution

While implementing a solution, the thumb rule is to finish it as soon as possible. Because the product is already live and they are doing continuous enhancements and bug fixes into the same. So, I need to apply a solution which requires minimal code changes and lesser efforts. So, we go with the following:

  • Implementing Dependency Injection : Previously, they created all the classes and created instances of the classes on other classes as per their need. So, created proper interfaces and used contractor based injection in most of the places but in some places where facing issues of circular dependency. For class libraries, create a Register method and put all the dependency registrations into that method. Later, I called that method from the API project’s dependency registration class.
  • Used Extension Methods and base classes to minify the code changes : We created many custom extension methods of the method due to changes in the calling structure of the method which exactly looks the same like .NET framework. So, in the existing code base, changes are implemented by importing the required namespace. Similarly, in the .NET framework, all the API controller classes are extended from APIController but in .NET 6 it is extended from ControllerBase. So, we created custom APIController classes and extended it from ControllerBase. In this way, you don't need to change the base class into all controllers.
  • Migrate Database First to EF Core : As EF Core does not provide database first entity framework support, we have to use the migrations toolkit provided by Microsoft. Using that toolkit, it provides several CLI commands. By running those commands, the database is updated / created with the model we have. After done with migrations, we manually written migration script for all of our stored procedure because it does not natively support automatic migration generation for stored procedures that were created in Entity Framework 6 (EF6) database first projects
  • Finding alternatives of System.Web namespace : closest alternative of system.web namespace is Microsoft.AspNetCore. So, I need to replace that class. But not only that, found following alternatives for essential items:
    • ASP.NET Core : We transitioned it from System.web for web-related functionality, to ASP.NET Core. It provides a modern, cross-platform framework for building web applications. ASP.NET Core includes features for handling HTTP requests, routing, authentication, authorization, and more.
    • HttpContext : The HttpContext class in ASP.NET Core provides similar functionality to the HttpContext class in System.Web. We accessed it within controllers and middleware to work with the current HTTP request and response.
    • Hosting : The Microsoft.AspNetCore.Hosting namespace provides classes and interfaces for hosting ASP.NET Core applications. It includes the IWebHost and IWebHostBuilder interfaces, which are used to configure and start the web host. We used IWebHostBuilder as a replacement for Server.MapPath of the .NET framework.
    • HttpRequest and HttpResponse : In ASP.NET Core, we used HttpRequest and HttpResponse classes from the Microsoft.AspNetCore.Http namespace. These classes offer similar functionality to their System.Web counterparts.
    • HttpClient : We replaced System.Net.Http.HttpClient class for making HTTP requests, with IHttpClientFactory interface.NET Core because it has following benefits:
      • It is a bit easier to mock the request while writing a unit test case and adds logging for all requests sent through clients created by the factory.
      • Naming and configuring logical HttpClient instances.
      • Build an outgoing request middleware to manage cross-cutting concerns around HTTP requests.
      • Integrates with Polly for transient fault handling.
      • Avoid common DNS problems by managing HttpClient lifetimes.
      • Adds logging for all requests sent through clients created by the factory.
  • Fetching configuration from AppSettings.json : In order to fetch the configuration from appsettings.json, we implemented the IOptions pattern. First we are going to create the custom class which contains all the properties which are required in configuration. After that, in program.cs or supported extension class method, we are registering it. So, whenever we need, we can directly inject it using DI. It means, we are only reading configuration from appsettings.json at application startup and use it anywhere we need because it is present in the memory.
  • Implementing Middleware : Same way created many other middlewares to fulfill the many other requirements. Some of them are as follows:
    • Authentication and Authorization : Created middleware t o handle authentication and authorization in web applications. It can intercept incoming requests, verify user credentials, and enforce access control policies before allowing access to protected resources.
    • Error Handling : Created exception middleware to handle all the exceptions in a single central place and logged those exceptions to the database as well as logged into the Azure monitor.
    • Request and Response Transformation : Created middleware which is used for adding checksum parameters and validates the checksum parameter. If matches then proceed further else return appropriate response.
    • Request Rate Limiting : Created middleware which can enforce rate limits on incoming requests to protect the application from abuse or denial-of-service attacks. They can track request counts per client IP address or user and reject requests that exceed predefined limits.
    • Security Headers : Created middlewares which can add security headers to the responses of web applications to enhance security. We included security headers like Content Security Policy (CSP) and Strict-Transport-Security (HSTS).
    • Request Filtering : Created middlewares which can inspect incoming requests and apply filtering rules based on specific criteria. For example, they can block requests containing malicious or unwanted content, filter out requests with specific query parameters, or enforce request validation rules.
  • Serilog implementation : We created our own implementation of Serilog Sink to implement Azure Monitor with it. Reason behind implementing Serilog is it has multiple Sinks based on certain conditions. If we wanted to write log some other places we can do it easily and Azure monitor because it has Kusto query. Based on that we can write our custom query and fetch the logs whenever we need. Based on that, we integrated Grafana to show logs in graph format. Due to that, monitoring becomes easy as well as we can create our custom alerts based on our custom Kusto query and send notifications via an email or message, etc.
  • Azure KeyVault Implementation : We have securely relocated sensitive information such as connection strings, API keys, ClientId, and ClientSecrets of banks from the web.config file. This approach ensures that the secrets are automatically versioned within Azure KeyVault, eliminating the need for manual updates. To incorporate these, we need to store ClientId, ClientSecret and baseUrl of Azure KeyVault into our code base or database, in the encrypted and base64 encoded way. By adopting this method, we have effectively removed secrets from our code base, enhancing security and maintaining better separation of concerns.
  • Properly Implemented Inheritance : To achieve proper inheritance and reduce repetition, the code has been refactored by implementing base classes. These base classes contain common properties and mapping logic for third-party API models, stored procedure parameters, ADO.NET DataRow mapping, and other objects. Additionally, base repository and service classes have been created to consolidate commonly used non-public methods. By organizing the code in this manner, the common functionality can be reused without duplicating it throughout the codebase.
  • Centralized API calling mechanism : We have implemented a generic helper method that facilitates making API calls with any method, and allows the API to return various types of content. This approach offers several benefits, including a single point of control for managing common operations. For instance, we can securely log all request and response parameters, ensuring the protection of sensitive information such as personally identifiable information (PII) and payment card industry (PCI) data. Additionally, we have integrated a quick retry mechanism using Polly to handle situations where the API returns an invalid response. This ensures robustness and improves the reliability of our API calls
  • Generic Filters : Building upon the advantages of properly implemented inheritance, we have leveraged it to create generic filters that accept a type parameter, ensuring it is extended from a specific base class. This approach offers several benefits, including the ability to write conditions and validations on common parameters easily. By moving the model-specific validations into the respective model classes, we can override the method defined in the base model and perform the required validations inside them. This simplifies the implementation, as we can now simply call the overridden method to perform the necessary validations for each specific model.
  • MassTransit Implementation : In order to fulfill the use case of conditionally switching between various message brokers, MassTransist is the best fit for the same. This ensured high availability, fault tolerance, and message durability. By adopting MassTransit, we gained numerous benefits. Firstly, MassTransit provided a centralized and flexible messaging infrastructure, enabling decoupled communication between services. This resulted in improved scalability, as services could be added or removed without impacting the overall system.
  • Migration from Newtonsoft.Json to system.text.json : We initiated the migration process with careful planning and execution, successfully replacing all references to Newtonsoft.Json with the native System.Text.Json library. The migration delivered substantial performance enhancements, reduced memory usage, and improved compatibility with the latest .NET Core platform. We capitalized on this opportunity to optimize our JSON processing practices by leveraging the advanced features of System.Text.Json. The seamless integration with Microsoft technologies and frameworks ensured a cohesive development experience and long-term compatibility. Throughout the migration, we addressed challenges associated with polymorphic deserialization errors, including inconsistencies and mismatches in type information during deserialization. Additionally, we resolved issues related to null values and case-sensitive type checking by creating custom JsonConverters. Notably, these challenges were particularly prominent when processing incoming requests to our API. As a result, we now have a more efficient and future-proof JSON processing solution for our application.

Azure DevOps Flow

diagram-img

Architectural Diagram

diagram-img

Technology we used

The goal is to provide a secure and scalable approach while migrating .NET Framework to .NET 6, we decided to use Azure Bus Service, RabbitMQ, MassTransit, .NET 6, Firebase & Mandrill.

icon
icon
icon
icon
icon
icon
icon
icon
icon
icon

Related Pages

  • Migrate Legacy / Desktop application to .NET 7 - Legal Agency

  • .NET Core custom eCommerce Solution - Digital Signature Leader

  • Microsoft Dotnet Development Portfolio

Frequently Asked Questions

  • What fintech services can you offer?

    We offer a wide range of fintech solutions, including mobile banking, online payment processing, financial analytics, and more.

  • Can you implement secure financial platform?

    Yes, we implement advanced security measures and encryption protocols to ensure the security of customer data and transactions.

  • Which payment gateway can you integrate in financial platform?

    We have hands of experience in integrating Stripe, Square, USAePay, PayPal, Authorize.NET & CCAvenue. We can integrate any payment gateway if they provide the API.

  • Can you maintain / enhance existing FinTech platform?

    Yes we take all types of maintenance & enhancement work. Our .NET developers are expert in debugging and understanding code written by other developers.

Trusted Customers

Contact Us About

By sending this form I confirm that I have read and accept Variance Infotech Privacy Policy

What happens next?

  • Our sales manager reaches out to you within a few days after analyzing your business requirements.
  • Meanwhile, we sign an NDA to ensure the highest level of privacy.
  • Our pre-sale manager presents project estimates and an approximate timeline.

We use cookies to provide better experience on our website. By continuing to use our site, you accept our Cookies and Privacy Policy.

Accept