ASP.NET Core Middleware – Write a Custom Middleware in Web API

ASP.NET Core Middleware concept is one of powerful features introduced, it gives us complete control over HTTP pipeline using Request and response. They effectively replacement for HttpModules and HttpHandlers.

ASP.NET docs explain middleware concept quite well, have look at it.

ASP.NET Core Middleware examples are UseMVC, UseStaticFiles, UseIdentity etc. They have specific purpose to do, thats why we might end with many of them.

In this article, we will create custom middleware to be used in ASP.NET Core Web API. Lets understand the scenario for writing this custom middleware.

  • Public APIs like Twitter, Google, Facebook etc provide us some sort of application key; naming them as “app-key”, “user-key”, “api-key” and so on.
  • Similar to above examples, we might have created Web API which provides a key to those who are registered.
  • Whenever a request hits our Web API, then we check if Request Headers contain this key or not then we move ahead to process the request positively or negatively.
  • We will write custom middleware that checks request header and takes required action.

My scenario is “A user registers in our system to generate a “user-key“; using this key all requests are sent. The Web API project will check if “user-key” exists or not in header. If exists move ahead to validate if key is part of our registered user, if not then respond back with 401 status code. If key not present in Header then it will be Bad Request.

Quick assumptions “Registered user-key’s are present in C# list, a repository is injected in StartUp.cs which checks if user key exists in C# list. We can read from database (any source) to check user key”.

Moving on from Basic Web API created using ASP.NET Core, we will create following files in our solution

  • Create “Middleware” folder in ContactsAPI project, then create C# class “UserKeyValidatorsMiddleware“.

UserKeyValidatorsMiddleware as ASP.NET Core Middleware

  • RequestDelegate helps us invoking next component in pipeline.
  • IContactsRepository is DI to help us validate “user-key” against data source using method “CheckValidUserKey“.
  • The _next property represents a delegate for the next component in the pipeline. Each component must also implement an async task called Invoke
  • In the Invoke method, we check if Request Header has “user-key” or not, if NO then return with Bad Request. If exists then check with against database if it exists or not. If NO then you are not Authorized is returned.
  • C# Region “ExtensionMethod“, provides user friendly name for this middleware when its placed in pipeline in StartUp.cs

Now lets update IContactsRepository to validate the user key

Open IContactsRepository.cs and ContactsRepository.cs; add below code.

 

Open Startup.cs to add following highlighted line of code in “Configure“. ApplyUserKeyValidation is extension method written above (Not mandatory to make extension method)

Now that we have created custom ASP.NET Core Middleware, added repository using DI and added it to pipeline. Let’s see it working. Use POSTMAN to test this Web API

Test 1: user-key doesn’t exists in Request Header.

ASP.NET Core Middleware

Test showing “User Key” not present in Request Header

Test 2: user-key exists but is INVALID

asp.net core middleware

user-key exists in Request Header but is INVALID

Test 3: user-key exists, its VALID and return JSON response also.

asp.net core middleware

Valid user-key exists and JSON response is seen

Refer ContactsAPI repo on Github for full source code. Let me know your thoughts on this.

You may also like...

8 Responses

  1. shishu singh says:

    Hi Mithun,

    I got this error while created a new project with your code

    Unable to resolve service for type ‘ContactsAPI.Repository.IContactsRepository’ while attempting to activate ‘ContactsAPI.Middleware.UserKeyValidatorsMiddleware’.

    at Microsoft.Extensions.Internal.ConstructorMatcher.CreateInstance(IServiceProvider provider)
    at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
    at Microsoft.AspNetCore.Builder.c__DisplayClass3_0.b__0(RequestDelegate next)
    at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

    Please help me out.

  2. Prafulla Paraskar says:

    Stumble upon this post after building something similar 🙂
    Very good write up.

    Given it is just an example, you may consider Hashset for vanilla string look-ups, blazing fast compared to List of string in real projects.

  3. James Wierzba says:

    Why not directly apply the middleware in Startup Configure method instead of creating an extension method?

  4. Samuel P says:

    Exactly what i was looking for thank you

  5. Leandro Abade says:

    great example, how to get the key in the current User controller?

Leave a Reply