Skip to main content

GraphQL API Integration In Asp.Net Core Application

Introduction:


GraphQL is a query language for your API and a server-side runtime for executing queries by using a type system you define for your data. GraphQL can be integrated into any framework like ASP.NET, Java, NestJs, etc and it isn't tied to any specific database or storage engine and is instead backed by your existing code and data.

How GraphQL API Different From Rest API:

  • GraphQL exposes a single end-point or route for the entire application, regardless of its responses or actions.
  • HTTP-POST is the only Http verb recommended by the GraphQL.
  • The client applications (consumers of API) can give instructions to GraphQL API about what type of properties to be returned in the response.

Building Blocks Of GraphQL API:

  • The main building blocks of GraphQL API is Schemas and Types.
  •  A 'Schema' in GrpahQL API describes the functionality available to the clients connect to API. Schema mostly consists of GraphQL Object Types, Queries, Mutations, etc.
  • Types likely to be called GraphQL Object Types. GraphQL Object Types represents the data source types return from API. GraphQL Object Types contains 'Fields' and 'Methods'. Fields are just properties in a class, 'Methods' are used to modify or conditionally change the field values based on client query.

Create ASP.NET Core Web API Project Template:

Let's start to learn about features in GraphQL, its implementation, and its integration into the Asp.Net Core application. Now create the Asp.Net Core Web API template.

GraphQL Nuget:

Open package manager console in VisualStudio to install GraphQL Nuget.
           Install-Package GraphQL -Version 2.4.0

Create Data Source Model:

Data Source Model means which represents a Table class. So add the new folder as 'Models', to that folder add a new class as 'Player.cs'
public class Player
{
 public int Id { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public int CurrentAge { get; set; }
 public string Teams { get; set; }
 public string PlayingRole { get; set; }
 public string BattingStyle { get; set; }
 public string BowlingStyle { get; set; }
}

Create A Data Repository And Register To Services:

A repository is a data access layer, where communication with the database goes. So add the new folder as 'Repositories', to that folder add two files like 'IPlayerRepository' and 'PlayerRepository'.

IPlayerRepository:
using System.Collections.Generic;
using GraphQLSample.Models;
namespace GraphQLSample.Repositories
{
    public interface IPlayerRepository
    {
        List<Player> GetAll();
    }
}

PlayerRepository:
using System.Collections.Generic;
using GraphQLSample.Models;
namespace GraphQLSample.Repositories
{
    public class PlayerRepository: IPlayerRepository
    {
        // later code will be updated
        // to get data from database
        public List<Player> GetAll()
        {
            return new List<Player>
            {
                new Player
                {
                    Id=1,
                    FirstName= "Rohit",
                    LastName = "Sharma",
                    CurrentAge = 32,
                    PlayingRole = "Opener",
                    BattingStyle = "Right-hand Bat",
                    BowlingStyle="spin",
                    Teams="India, Mumbai, Mumbai Indians"
                }
    // display purpose items hidden , while testing add more items
            };
        }
    }
}
Here repository 'GetAll()' method returning all the players(later code will be updated to access players from database).

Register Repositories In ConfigurationServices Method In StartUp.cs:
services.AddScoped<IPlayerRepository, PlayerRepository>();
By default, the Dotnet Core application configured with dependency injection, so the creation of an object to any service or repository classes taken care of by it. AddScoped() represents an object created per request.

ObjectGraphType:

  • 'GraphQL.Types.ObjectGraphType' class represents Types in GraphQL which we discussed as one of the core concepts in GraphQL.
  •  GraphQL is not bound to any specific language or framework, so it can not understand CSharp POCO( Plain Old CLR Object ) classes directly. 
  • So to represent GraphQL Type, CSharp Classes need to inherit 'GraphQL.Types.ObjectGraphType'. 
  • After inheriting ObjectGraphType in the constructor we need to register our own class properties as 'Field' types which is understandable by GraphQL.
Let's implement a type that inherits the ObjectGraphType in our sample. So add the new folder as 'GrpahQLTypes', to that folder add new file 'PlayerType.cs'

PlayerType.cs:
using GraphQL.Types;
using GraphQLSample.Models;

namespace GraphQLSample.GraphQLTypes
{
    public class PlayerType:ObjectGraphType<Player>
    {
        public PlayerType()
        {
            Field(_ => _.Id);
            Field(_ => _.FirstName);
            // description is an self 
            //explanatory extenstion method which is options
            Field(_ => _.LastName).Description("last name of a player");
            Field(_ => _.CurrentAge);
            Field(_ => _.Teams);
            Field(_ => _.PlayingRole);
            Field(_ => _.BattingStyle);
            Field(_ => _.BowlingStyle);
        }
    }
}
  • Here we have a model 'Player' which CSharp POCO classes, which can't be understood by GraphQL directly. 
  • To make 'Player' to GraphQL Type, we have created a new class 'PlayerType' which inherits 'GraphQL.Types.ObjectGrpahType<T>'. Type took by ObjectGraphType is 'Player' to represent it as GraphQLType. 
  • All the properties of 'Player' class returning as 'Field' types which can be understood by GraphQL.

Schema:

  • Schema is one of the main building blocks of GraphQL API. 
  • Schema mainly consists of Query, Mutation, Types, etc. Query in Schema is an ObjectGraphType, but it is like Root or Parent ObjectGraphType. 
  • Schema Query held all other ObjectGraphType of entire application, more or less it acts as a Data Source to clients consuming GraphQL API. 
  • Based on the client's request this Query in Schema serves data.
Let's start to create a Query in the Schema of GraphQL API. In the 'GraphQLTypes' folder add a new file name it as 'RootQuery.cs'

RootQuery.cs:
using GraphQL.Types;
using GraphQLSample.Repositories;

namespace GraphQLSample.GraphQLTypes
{
    public class RootQuery:ObjectGraphType
    {
        public RootQuery(IPlayerRepository _playerRepository)
        {
            Field<ListGraphType<PlayerType>>("players", resolve: context =>
             {
                 return _playerRepository.GetAll();
             });
        }
    }
}
  • Here all players returning under field name 'players' and Field register with 'PlayerType'(ObjectGraphType). 
  • Similarly, all POCO classes which represent a table will have their individual ObjectGraphType(like PlayerType for Player class) and these all ObjectGraphType will be registered as Field type in RootQuery in our application. 
Register RootQuery in ConfigureServices method in Startup.cs
 services.AddScoped<RootQuery>();
Now in the 'GraphQLTypes' folder add a new file and name as 'RootSchema.cs'. By default GraphQL Dotnet Library provides us 'Schema' and 'ISchema' entities, but we are creating custom schema like 'RootSchema' because to consume the benefits of Dependency Injection. Our 'RootSchema' inherits both 'GrpahQL.Types.Schema', 'GraphQL.Types.ISchema' to represent a GraphQL Schema.

RootSchema:
using GraphQL;
using GraphQL.Types;

namespace GraphQLSample.GraphQLTypes
{
    public class RootSchema:Schema, ISchema
    {
        public RootSchema(IDependencyResolver resolver):base(resolver)
        {
            Query = resolver.Resolve<RootQuery>();
        }
    }
}

GraphQL NuGet library comes with inbuild Dependency Resolver. 'Schema' class has 'GraphQL.IDependencyResolver' as property, so that it can resolve all ObjectGraphType it needed.
.
Register Schema and IDependencyResolver in method ConfigurationServices in Startup.cs:
services.AddScoped<IDependencyResolver>(_ => new FuncDependencyResolver(_.GetRequiredService));
services.AddScoped<ISchema, RootSchema>();
'GraphQL.FuncDependencyResolver' implements 'GraphQL.IDependencyResolver'.

Create GraphQL API EndPoint:

Now create a new Web API Controller as 'GraphQLController' and the controller contains only one action method that supports Http-Post verb. In the model, folder add new file 'GraphQLQueryDto.cs' files that represent the post data payload entity.

GraphQLQueryDto.cs:
namespace GraphQLSample.Models
{
    public class GraphQLQueryDto
    {
        public string Query { get; set; }
    }
}
Query property represents data to query the GraphQL API.

GraphQLController.cs:
[Route("graphql")]
public class GraphQLController : Controller
{
 private readonly ISchema _schema;
 private readonly IDocumentExecuter _executer;
 public GraphQLController(ISchema schema, IDocumentExecuter executer)
 {
  _schema = schema;
  _executer = executer;
 }

 [HttpPost]
 public async Task<IActionResult> Post([FromBody] GraphQLQueryDto query)
 {
  var result = await _executer.ExecuteAsync(_ =>
  {
   _.Schema = _schema;
   _.Query = query.Query;
  }).ConfigureAwait(false);

  if(result.Errors?.Count > 0)
  {
   return Problem(detail: result.Errors.Select(_ => _.Message).FirstOrDefault(), statusCode:500);
  }
  return Ok(result.Data);
 }
}
  • Here [Route("graphql")] is route decorator, it says controller configured with Web API attribute routing. 
  • 'GraphQL.ISchema' is a Schema of GraphQL API, the instance of schema was created by constructor injection. 
  • 'GraphQL.IDocumentExecuter' has async GraphQL query executor. On successful execution of IDocumentExecuter returns data. On Error, execution returns an error message to the clients consuming GraphQL API.
Register 'IDocumentExecuter' in the ConfigureService method in Startup.cs:
services.AddSingleton<IDocumentExecuter, DocumentExecuter>();

Fields:

GraphQL is about asking for specific fields on objects on the server. Let's test API by requesting Fields.

Request Query:
query {
 players {
  id
  firstName
 }
}

Here GraphQL Query just looks like almost similar to JSON Object. 'query' is represented as root query. 'players', 'id', 'firsName' are registered Fields in ObjectGraphQLType as below:
// field registered in RootQuery.cs
Field<ListGraphType<PlayerType>>("players", resolve: context =>
{
 // logic to server 'players'
});

// field registered in PlayerType.cs
Field(_ => _.Id);
Field(_ => _.FirstName);

Now test API as below:
We got 500 error status code and error message shows 'PlyerType' has been not registered. I allowed this error purposefully, because to aware that every ObjectGraphQLType must be registered in Startup.cs

Resolve No Service Registered For ObjectGraphQLType:

Now register PlayerType in the ConfigureService method in Startup.cs:
services.AddSingleton<PlayerType>();

Now test API again:

Query Arguments To Filter Data :

In GraphQL we can pass an argument to filter the GraphQL API. Since in GraphQL data is coming based on Fields requested, it is possible to pass arguments to the fields to filter the data.

RootQuery.cs:
public class RootQuery:ObjectGraphType
{
 public RootQuery(IPlayerRepository _playerRepository)
 {
  Field<ListGraphType<PlayerType>>("players", resolve: context =>
   {
    
    return _playerRepository.GetAll();
   });

  Field<ListGraphType<PlayerType>>("filteredPlayers",
   arguments: new QueryArguments
   {
      new  QueryArgument<StringGraphType> { Name = "firstName"}
   },
   resolve: context =>
   {
    string firstName = context.GetArgument<string>("firstName");
    return _playerRepository.GetAll().Where(_ => _.FirstName.ToLower() == firstName.ToLower()).ToList();
   });
 }
}
  • Here we added a new Field with name 'filteredPlayers'. 
  • 'ListGraphType' is collection representation in GraphQL. 
  • Filed takes an 'arguments' as input parameter and its type is 'QueryArguments', here we capturing our argument like 'firstName' which is passed from the client to GraphQL API. Arguments that are captured here will be available from the context of Field.
  • 'StringGraphType' is equivalent to 'string' type in dotnet. 
  • From 'resolve' which is the input parameter of Field, we are getting the value of our argument like 'firstName' from field context. Based on the argument value filter the data and send to the client.
Request query with arguments:
query {
 filteredPlayers(firstName: "rohit") {
  id
  firstName
 }
}

Now test the GraphQL API:

Aliases:

We can observe that field name and API result object names are matching. By looking at the previous result object whose name is "filteredPlayers" is like more self-explanatory which might not look good in the JSON result object for clients consuming the GraphQL API. "Players" looks ideal name for the result JSON Object, but we can not use the "Players" name for argument query because of the normal query without argument using it. So this problem can be overcome by using Aliases names in the query fields. The server will return data by using the aliases' names.

Aliases Query:
query {
 players: filteredPlayers(firstName: "rohit") {
  id
  firstName
 }
}
To test the aliases name, test the API  with arguments query:

Fragments:

A comparison between two records in GraphQL API is very easy. Let's do a comparison using the below query

The query for comparison (without Fragments):
query {
 leftPlayer: filteredPlayers(firstName: "rohit") {
  id
  firstName
  lastName
 }
 rigthPlayer: filteredPlayers(firstName: "virat") {
  id
  firstName
  lastName
 }
}
Now test GraphQL API:
Here in GraphQL API, we are getting comparison data in a perfect way without doing any work at the server-side. But if we carefully observe queries constructed with duplicate fields, which will be tedious if the fields are a high number.

So to resolve these duplicate fields, GraphQL provided an option called Fragments where a set of similar fields will be grouped to a set.
The Query for comparison with Fragment:
query {
 leftComparison: filteredPlayers(firstName: "rohit") {
  ...props
 }
 rightComparison: filteredPlayers(firstName: "virat") {
  ...props
 }
}
fragment props on PlayerType {
 id
 firstName
 lastName
}

  • Here 'fragment' keyword represents GraphQL Fragment. 
  • 'props' defines the name of the fragment. 
  • 'pops on PlayerType' represents a fragment working on which type of ObjectGrphQLType(example from our sample PlayerType is an ObjectGraphQLType). 
  • A fragment was enclosed with set fields grouped. 
  • Inside query we can observe instead of mentioning fields, we have used fragment name prop which dynamically replaces fields at the time of query execution on the server.

Now test GraphQL API:

Accessing Data From Database:

We are going to create a DbContext, code-first approach with an existing database. Let's first install NuGet packages related to entity-framework as below.
        Install-Package Microsoft.EntityFrameworkCore -Version 3.0.1
        Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.0.1
Create a new folder name as 'Data', inside add the new file as SportsContext.cs as below:
using GraphQLSample.Models;
using Microsoft.EntityFrameworkCore;

namespace GraphQLSample.Data
{
    public class SportsContext : DbContext
    {
        public SportsContext(DbContextOptions<SportsContext> options) : base(options)
        {

        }

        public DbSet<Player> Player { get; set; }
    }
}
Register SportsContext in ConfigureServices method in Startup.cs as below:
services.AddDbContext<SportsContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("SportsContext")));
Add database connection string in "appSettings.json". Now update the 'PlayerRepository.cs' as below:
using System.Collections.Generic;
using System.Linq;
using GraphQLSample.Data;
using GraphQLSample.Models;

namespace GraphQLSample.Repositories
{
    public class PlayerRepository: IPlayerRepository
    {
        private readonly SportsContext _sportsContext;
        public PlayerRepository(SportsContext context)
        {
            _sportsContext = context;
        }
        public List<Player> GetAll()
        {
            return _sportsContext.Player.ToList();
        }
    }
}

GraphQL Query to test:
query {
 players {
  id
  firstName
  lastName
 }
}
Now test GraphQL API:

Mutations:

GraphQL Mutations represent changing the state of data at the server-side, which means to create or update or delete data. To perform mutation you need to have the root mutation object of type ObjectGraphType. Like RootQuery which holds all ObjectGraphType Fields to fetch the data, we need to create RootMutation which holds all ObjectGraphType Fields to create or update or delete the data.

Let's write logic to add a new item in  'PlayerRepository.cs' file as below:
public Player AddPalyer(Player player)
{
 _sportsContext.Player.Add(player);
 _sportsContext.SaveChanges();
 return player;
}
IPlayerRepositroy.cs:
Player AddPalyer(Player player);

To capture the data of the object posted from the client, we need to create GraphQL type which inherits 'GraphQL.Types.InputObjectGraphType<T>'. InputObjectGraphType looks similar to ObjectGraphType, but InputObjectGraphType to capture the data from client wherea as ObjectGraphType to serve the type of data to clients. Now in 'GraphQLTypes' folder add a new file as 'InputPlayerType.cs'

InputPlayerType.cs:
using GraphQL.Types;
using GraphQLSample.Models;

namespace GraphQLSample.GraphQLTypes
{
    public class InputPlayerType:InputObjectGraphType<Player>
    {
        public InputPlayerType()
        {
            Name = "InputPlayerType";
            Field(_ => _.Id);
            Field(_ => _.FirstName);
            // description is an self 
            //explanatory extenstion method which is options
            Field(_ => _.LastName).Description("last name of a player");
            Field(_ => _.CurrentAge);
            Field(_ => _.Teams);
            Field(_ => _.PlayingRole);
            Field(_ => _.BattingStyle);
            Field(_ => _.BowlingStyle);
        }
    }
}
Now Register InputPlayerType in ConfigureServices method in Startup.cs:
services.AddSingleton<InputPlayerType>();
Now in 'GraphQLTypes' folder create a new file 'RootMutation.cs' as below:
using GraphQL.Types;
using GraphQLSample.Models;
using GraphQLSample.Repositories;

namespace GraphQLSample.GraphQLTypes
{
    public class RootMutation : ObjectGraphType
    {

        public RootMutation(IPlayerRepository playerRepository)
        {
            Field<PlayerType>(
                "addPlayer",
                arguments: new QueryArguments
                {
                    new QueryArgument<InputPlayerType>(){ Name = "player" }
                },
                resolve: context =>
                {
                    var player = context.GetArgument<Player>("player");
                    return playerRepository.AddPalyer(player);
                }
                );
        }
    }
}
Now configure RootMutation in RootSchema.cs as below:
public RootSchema(IDependencyResolver resolver):base(resolver)
{
 Query = resolver.Resolve<RootQuery>();
 Mutation = resolver.Resolve<RootMutation>();
}
Now Register RootMutation in ConfigureSevices method in Startup.cs as below:
services.AddScoped<RootMutation>();
Now modify 'GraphQLQueryDto' as below
public class GraphQLQueryDto
{
    public string Query { get; set; }
    public string Variables { get; set; }
}
Here 'Variables' property is like input data to 'Query' property. Now update 'GraphQLController' post method as below:
var result = await _executer.ExecuteAsync(_ =>
{
 _.Schema = _schema;
 _.Query = query.Query;
 _.Inputs = query.Variables?.ToInputs();
 
}).ConfigureAwait(false);
The variable value was assigned to the "Inputs" type in DocumentExecuter, where this variable values passed as data to 'Query' variables at runtime.

The query for Mutation:
mutation($player: InputPlayerType) {
 addPlayer(player: $player) {
  id
  firstName
 }
}
  • mutation keyword to represent GraphQL Mutations. 
  • '$player' is a variable whose values will pass from GraphQL 'Variables'.  
  • 'InputPlayerType' is assigned a type of '$player', it should match with the name of the 'InputObjectGraphType' we declared in the above steps. 
  • 'addPlayer' represents Field name in 'RootMutation' as we mentioned above steps. 'player'  argument of 'addplayer' Field.
Variables of the above Mutation query:
{
"player":{
  "id":0
  "firstName": "Shikar",
  "lastName": "Dhawan",
  "currentAge": 30,
  "teams": "India",
  "playingRole": "Opening Batsman",
  "battingStyle": "Left-hander",
  "bowlingStyle": "N/A"
}
}
Variable is a plain JSON Object.
Now test the API with GraphQL Mutations

Summary:

We have discussed the core feature of the GraphQL API. We learned how GraphQL API is different from REST API. We did a hands-on sample of integrating GraphQL API into the Asp.Net Core application. 

Source Code:


Follow Me:

Comments

  1. Best tutorial I found so far - and nicely laid out. Thank-you.

    Just having an issue with the final sample where you explain the mutation. The query arg in the controller is null no matter how I format it in postman.
    I downloaded the code to make sure I followed the examples correctly and it appears I have.
    Any ideas?

    ReplyDelete
    Replies
    1. Hi DominionZA,
      payload for mutation
      {
      "query":"mutation($player: InputPlayerType) { addPlayer(player:$player){id firstName} }",
      "variables":"{\"playe\":{\"id\":0, \"firstName\":\"rahul\",\"lastName\":\"KL\",\"currentAge\":30,\"teams\":\"India\",\"playingRole\":\"Wicket Keeper\",\"battingStyle\":\"Left-hander\",\"bowlingStyle\":\"N/A\"}}"
      }

      Delete
  2. How to integrate existing API using GraphQL/HotChocolate to fetch data from the existing API?

    ReplyDelete

Post a Comment

Popular posts from this blog

.NET6 Web API CRUD Operation With Entity Framework Core

In this article, we are going to do a small demo on AspNetCore 6 Web API CRUD operations. What Is Web API: Web API is a framework for building HTTP services that can be accessed from any client like browser, mobile devices, desktop apps. In simple terminology API(Application Programming Interface) means an interface module that contains a programming function that can be requested via HTTP calls to save or fetch the data for their respective clients. Some of the key characteristics of API: Supports HTTP verbs like 'GET', 'POST', 'PUT', 'DELETE', etc. Supports default responses like 'XML' and 'JSON'. Also can define custom responses. Supports self-hosting or individual hosting, so that all different kinds of apps can consume it. Authentication and Authorization are easy to implement. The ideal platform to build REST full services. Create A .NET6 Web API Application: Let's create a .Net6 Web API sample application to accomplish our

Blazor WebAssembly Custom Authentication From Scratch

In this article, we are going to explore and implement custom authentication from the scratch. In this sample, we will use JWT authentication for user authentication. Main Building Blocks Of Blazor WebAssembly Authentication: The core concepts of blazor webassembly authentication are: AuthenticationStateProvider Service AuthorizeView Component Task<AuthenticationState> Cascading Property CascadingAuthenticationState Component AuthorizeRouteView Component AuthenticationStateProvider Service - this provider holds the authentication information about the login user. The 'GetAuthenticationStateAsync()' method in the Authentication state provider returns user AuthenticationState. The 'NotifyAuthenticationStateChaged()' to notify the latest user information within the components which using this AuthenticationStateProvider. AuthorizeView Component - displays different content depending on the user authorization state. This component uses the AuthenticationStateProvider

How Response Caching Works In Asp.Net Core

What Is Response Caching?: Response Caching means storing of response output and using stored response until it's under it's the expiration time. Response Caching approach cuts down some requests to the server and also reduces some workload on the server. Response Caching Headers: Response Caching carried out by the few Http based headers information between client and server. Main Response Caching Headers are like below Cache-Control Pragma Vary Cache-Control Header: Cache-Control header is the main header type for the response caching. Cache-Control will be decorated with the following directives. public - this directive indicates any cache may store the response. private - this directive allows to store response with respect to a single user and can't be stored with shared cache stores. max-age - this directive represents a time to hold a response in the cache. no-cache - this directive represents no storing of response and always fetch the fr

.Net5 Web API Managing Files Using Azure Blob Storage

In this article, we are going to understand the different file operations like uploading, reading, downloading, and deleting in .Net5 Web API application using Azure Blob Storage. Azure Blob Storage: Azure blob storage is Microsoft cloud storage. Blob storage can store a massive amount of file data as unstructured data. The unstructured data means not belong to any specific type, which means text or binary data. So something like images or pdf or videos to store in the cloud, then the most recommended is to use the blob store. The key component to creating azure blob storage resource: Storage Account:- A Storage account gives a unique namespace in Azure for all the data we will save. Every object that we store in Azure Storage has an address. The address is nothing but the unique name of our Storage Account name. The combination of the account name and the Azure Storage blob endpoint forms the base address for each object in our Storage account. For example, if our Storage Account is n

A Small Guide On NestJS Queues

NestJS Application Queues helps to deal with application scaling and performance challenges. When To Use Queues?: API request that mostly involves in time taking operations like CPU bound operation, doing them synchronously which will result in thread blocking. So to avoid these issues, it is an appropriate way to make the CPU-bound operation separate background job.  In nestjs one of the best solutions for these kinds of tasks is to implement the Queues. For queueing mechanism in the nestjs application most recommended library is '@nestjs/bull'(Bull is nodejs queue library). The 'Bull' depends on Redis cache for data storage like a job. So in this queueing technique, we will create services like 'Producer' and 'Consumer'. The 'Producer' is used to push our jobs into the Redis stores. The consumer will read those jobs(eg: CPU Bound Operations) and process them. So by using this queues technique user requests processed very fastly because actually

.Net5 Web API Redis Cache Using StackExchange.Redis.Extensions.AspNetCore Library

In this article, we are going to explore the integration of Redis cache in .Net5 Web API application using the 'StackExchange.Redis.Exntensions' library. Note:- Microsoft has introduced an 'IDistributedCache' interface in dotnet core which supports different cache stores like In-Memory, Redis, NCache, etc. It is simple and easy to work with  'IDistributedCache', for the Redis store with limited features but if we want more features of the Redis store we can choose to use 'StackExchange.Redis.Extensions'.  Click here for Redis Cache Integration Using IDistributedCache Interface . Overview On StackExchange.Redis.Extnesions Library: The 'StackExchange.Redis.Extension' library extended from the main library 'StackExchange.Redis'. Some of the key features of this library like: Default serialization and deserialization. Easy to save and fetch complex objects. Search key. Multiple Database Access Setup Redis Docker Instance: For this sampl

Usage Of CancellationToken In Asp.Net Core Applications

When To Use CancellationToken?: In a web application request abortion or orphan, requests are quite common. On users disconnected by network interruption or navigating between multiple pages before proper response or closing of the browser, tabs make the request aborted or orphan. An orphan request can't deliver a response to the client, but it will execute all steps(like database calls, HTTP calls, etc) at the server. Complete execution of an orphan request at the server might not be a problem generally if at all requests need to work on time taking a job at the server in those cases might be nice to terminate the execution immediately. So CancellationToken can be used to terminate a request execution at the server immediately once the request is aborted or orphan. Here we are going to see some sample code snippets about implementing a CancellationToken for Entity FrameworkCore, Dapper ORM, and HttpClient calls in Asp.NetCore MVC application. Note: The sample codes I will show in

Endpoint Routing In Asp.Net Core

How Routing Works In  Core 2.1 And Below Versions?: In Asp.Net Core routing is configured using app.UseRouter() or app.UseMvc() middleware. app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); Here in Dotnet Core version 2.1 or below versions on the execution of route middleware request will be navigated appropriate controller matched to the route. An operation or functionality which is dependent on route URL or route values and that need to be implemented before the execution of route middleware can be done by accessing the route path from the current request context as below app.Use(async (context, next) => { if(context.Request.Path.Value.IndexOf("oldvehicle") != -1) { context.Response.Redirect("vehicle"); } else { await next(); } }); app.UseMvc(routes => { routes.MapRoute( name: "vehicleRoute", template: "vehicle", defaul

Asp.Net Core MVC Form Validation Techniques

Introduction: Form validations in any applications are like assures that a valid data is storing on servers. All programing frameworks have their own individual implementations for form validations. In Dotnet Core MVC application server-side validations carried on by the models with the help of Data Annotations and the client-side validations carried by the plugin jQuery Unobtrusive Validation. jQuery Unobtrusive Validation is a custom library developed by Microsoft based on the popular library  jQuery Validate . In this article, we are going to learn how the model validation and client-side validation works in Asp.Net Core MVC Application with sample examples. Getting Started: Let's create an Asp.Net Core MVC application project using preferred editors like Microsoft Visual Studio or Microsoft Visual Studio Code. Here I'm using Visual Studio. Let's create an MVC controller and name it as 'PersonController.cs' and add an action method as bel

NestJS File Upload

In this article, we are going to understand the steps to create a file uploading endpoint in the NestJS application. Key Features In NestJS File Upload: Let us know some key features of NestJS file upload before implementing a sample application. FileInterceptor: The 'FileInterceptor' will be decorated on top of the file upload endpoint. This interceptor will read single file data from the form posted to the endpoint. export declare function FilesInterceptor(fieldName: string, localOptions?: MulterOptions): Type<NestInterceptor>; Here we can observe the 'fieldName' first input parameter this value should be a match with our 'name' attribute value on the form file input field. So our interceptor read our files that are attached to the file input field. Another input parameter of 'MulterOptions' that provides configuration like file destination path, customizing file name, etc. FilesInterceptor: The 'FilesInterceptor' will be decorated on t