Click here to Skip to main content
15,867,330 members
Articles / Web Development / ASP.NET

Basic Steps to Migrate HTTP Handlers and HTTP Modules to ASP.NET Core Middleware.

Rate me:
Please Sign up or sign in to vote.
4.76/5 (6 votes)
6 Dec 2016CPOL6 min read 30.9K   8   5
Migrating HTTP Handlers and HTTP Modules to ASP.NET Core Middlerware

Introduction

My team was migrating Angular JS 1.5.XX with MVC 5 to .NET Core Web App with Angular 2.0. While doing the same, we realized that we were using HTTP Handlers in the project. And we decided to migrate them too even though this was a bold decision ;-). While migrating, we faced challenges and finally, we were able to migrate. Then I decided why I don't write an article which gives a high-level introduction on the migration. And the outcome is this article :-).

This article provides basic steps to be followed while migrating HTTP Handlers & Modules to ASP.NET Core Middleware. This article will not deep dive into HTTP Handlers & Modules nor on the ASP.NET Core Middleware. I would just use the Response object to display the output in the Web browser. I wanted to keep this article to be very simple. In real time scenarios Handlers & Modules involve critical logic for the application. My intention is to give a high-level introduction to the HTTP Handlers & Module and ASP.NET Core Middleware with code samples as I think that would kick start the understanding of ASP.NET Core Middleware.

In this article, I have used VS 2015 Update 3.

I have planned for this article like below:

  1. HTTP Handlers
  2. HTTP Modules
  3. Create a VS project with a sample HTTP Handler & Module
  4. ASP.NET Middleware & key methods of it
  5. Create a VS project with a sample ASP.NET Core Middleware
  6. Migrating the HTTP Handler & Module created in Step#3 to ASP.NET Middleware
  7. Key differences between HTTP Handler & Module with ASP.NET Core Middleware

1. HTTP Handlers

HTTP Handlers run in response for each of the requests made to the Web Server. The most common are .aspx or .rss feeds. HTTP Handlers can be made for your own requirements and can render the output to the web browser. They are created by implementing IHttpHandler's ProcessRequest().

C#
public class CustomReportHandler : IHttpHandler
    {
        #region IHttpHandler Members 
        public bool IsReusable
        {
            get { return false; }
        } 
        public void ProcessRequest(HttpContext context)
        {
            var response = context.Response; 
            response.Write
            ("<h2>This handler is written for processing files with .report extension<h2>");
           
          //more logic follows...
        } 
        #endregion
    }

2. HTTP Modules

HTTP Modules are classes which are called for every request that is made to the application. These have access to the life-cycle event of an HTTP pipeline. HTTP Modules can be made for your own requirements by implementing IHttpModule's Init().

C#
public class CustomModule : IHttpModule
    {
        #region IHttpModule Members 
        public void Dispose()
        {
            //clean-up code here.
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += (source, arguments) =>
            {
                var httpApplication = (HttpApplication)source;
                var httpContext = httpApplication.Context; 
                httpContext.Response.Write("<h3>Custom module started the begin request</h3>");
               
               // More logic goes here.... 
              //httpApplication.CompleteRequest();// if you want to short-circut the request,
                                                  // then call the CompleteRequest().
            }; 
           
          context.EndRequest += (source, arguments) =>
            {
                var httpApplication = (HttpApplication)source;
                var httpContext = httpApplication.Context; 
                httpContext.Response.Write("<h3>Custom module completed the request</h3>"); 
               
               // More logic goes here....
            };
        } 
        #endregion

3. Create a VS Project with a Sample HTTP Handler & Module

  • Open VS 2015 and create a blank solution by name "MigratingHttpHandlersModulesToMiddleware". You give any name to it.
  • Add a New Project (ASP.NET Web Application) by name "CustomHandlersModules" and choose "Empty" template.
  • Create a class by name "CustomReportHandler" and implement the IHttpHandler. You can copy the code snippet from the HTTP Handlers section from the above.
    • Update the Web.config file with below entries:
      HTML
      <!--Under configuration - system.webServer - handlers section add below:-->
      <add name="CustomReportHandler" verb="*" path="*.report" 
      type="CustomHandlersModules.CustomReportHandler" resourceType="Unspecified"/> 
    • This handler will run in response for each of the requests made to the web application for a resource with .report extension.
    • Press Ctrl + F5 and http://localhost:29342/test.report. Your port might vary.
    • You would get the output as: This handler is written for processing files with .report extension at web browser.
  • Create a class by name "CustomModule" and implement the IHttpModule. You can copy the code snippet from the HTTP Modules section from the above.
    • Update the Web.config file with below entries:
      HTML
      <!--Under configuration - system.webServer - modules section add below:-->
      <add name="CustomModule" type="CustomHandlersModules.CustomModule"/>
    • Press Ctrl + F5 and http://localhost:29342/test.report. Your port might vary.
    • You would get the output as:
      Custom module started the begin request.
      This handler is written for processing files with .report extension.
      Custom module completed the request.

at the web browser.

4. ASP.NET Middleware & Its Key Methods

Till now, what we have seen was implementation of Handler & Modules which we all were used to implementing. Now, we will move on to the interesting topic of ASP.Core which is Middleware.

What is Middleware? They are the code which are added to the application pipeline. The code would apply some logic and would handle the request in the pipeline.

In order to implement, we can use 4 methods of the Application Builder which are passed to the Request Delegate.

  • Run: This will terminate the http pipeline.
  • Use: Adds the middleware to the request pipeline.
  • Map: This is used to match request delegates based on a request's path.
  • MapWhen: This method supports predicate-based middleware branching, allowing separate pipelines.

When you create a core application, the entry point is Startup.cs. This class has two methods, Configure() and ConfigureServices(). Configure() is a place where all the middleware are defined and executed. ConfigureServices() is a place for all the Services which the application uses.

You can find more documentation about them at https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware.

Now that we have the basic understanding, let's create the ASP.NET Core application.

5. Create a VS Project with a Sample ASP.NET Core Middleware

  • Open VS 2015 solution, add a New Project with ASP.NET Core Web Application (.NET Core) template. Name it as "CustomMiddlewareForHttpHandlersModules" with Blank template.
  • At the Startup.cs, add the following before app.Run().
    C#
    app.Use(async (context, next) => {
    
                   await context.Response.WriteAsync("Custom call!!!!! <br/>");
                   await next.Invoke();
               });
    
  • Press Ctrl + F5. You would see the above response output with the Hello World! at the web browser.

As we have seen the basic middleware, let's jump start with the migration of the Handler and then with Module.

6. Migrating the HTTP Handler & Module Created in Step#3 to ASP.NET Middleware

6a. Migration HTTP Handler

In this section, we would migrate the Handler which we have created in Step#3.

  • Add a class by name "CustomHanlderMiddleware" and have the following code in it.
    C#
    public class CustomHanlderMiddleware
        {
            private RequestDelegate _next;
    
            public CustomHanlderMiddleware(RequestDelegate next)
            {
                _next = next;
            }
    
            public async Task Invoke(HttpContext context)
            {
                await context.Response.WriteAsync
                ("<h2>This handler is written for processing files with .report extension<h2>");
    
                //more logic follows...
            }
        }
  • In order to use the above created CustomHandlerMiddleware in the request pipeline, we need to create an extension method on the ApplicationBuilder. Create a class with name "CustomMiddlewareExtensions" and place the code like below:
    C#
    public static class CustomMiddlewareExtensions
        {
            public static IApplicationBuilder UseCustomHanlderMiddleware
                                          (this IApplicationBuilder builder)
            {
                return builder.UseMiddleware<CustomHanlderMiddleware>();
            }
        }
  • At the Startup.cs, place the below code just above the app.Run().
    C#
    app.Use(async (context, next) => {
    
         await context.Response.WriteAsync("Custom call!!!!! <br/>");
         await next.Invoke();
     });
    
     // For Handler
     app.MapWhen(context => context.Request.Path.ToString().EndsWith(".report"),
         appBuilder => {
             appBuilder.UseCustomHanlderMiddleware();
         });
    
     app.Run(async (context) =>
     {
         await context.Response.WriteAsync("Hello World!");
     });
    
  • next.Invoke() method does the invocation of the next request delegate on the pipeline. We can terminate the invocation by not calling the next.

6b. Migration HTTP Module

In this section, we would migrate the Module which we have created in Step#3.

  • Add a class by name "CustomModuleMiddleware". And have the below code in it:
    C#
    public class CustomModuleMiddleware
        {
            private RequestDelegate _next;
            public CustomModuleMiddleware(RequestDelegate next)
            {
                _next = next;
            }
            public async Task Invoke(HttpContext context)
            {
                await context.Response.WriteAsync("<h3>Custom module started the begin request</h3>");
    
                await _next.Invoke(context);
    
                await context.Response.WriteAsync("<h3>Custom module completed the request</h3>");
            }
        }
  • At the CustomerMiddlewareExtensions.cs, create an extension method which adds the middleware in the request pipeline. And the class should look like below:
    C#
    public static class CustomMiddlewareExtensions
        {
            public static IApplicationBuilder UseCustomHanlderMiddleware
                                      (this IApplicationBuilder builder)
            {
                return builder.UseMiddleware<CustomHanlderMiddleware>();
            }
            public static IApplicationBuilder UseCustomModuleMiddleware
                                      (this IApplicationBuilder builder)
            {
                return builder.UseMiddleware<CustomModuleMiddleware>();
            }
        }
  • At the Startup.cs, place the below code just above the app.Run().
    C#
    app.Use(async (context, next) => {
    
         await context.Response.WriteAsync("Custom call!!!!! <br/>");
         await next.Invoke();
     });
    
     // For Module
     app.UseCustomModuleMiddleware();
    
     // For Handler
     app.MapWhen(context => context.Request.Path.ToString().EndsWith(".report"),
         appBuilder => {
             appBuilder.UseCustomHanlderMiddleware();
         });
    
     app.Run(async (context) =>
     {
         await context.Response.WriteAsync("Hello World!");
     });
    
  • Press Ctrl + F5. http://localhost:31736/test.report

And finally, we have migrated the Handlers & Modules to ASP.NET Core Middleware. In order to see the same output, you can comment out the app.Use() and app.Run().

7. Key Differences between HTTP Handler & Module with ASP.NET Core Middleware

  • Web.config:
    • For Handler & Modules: We have to modify
    • For ASP.NET Core: No need to modify
  • Application Life Cycle:
    • For Handler & Modules: We have it
    • For ASP.NET Core: It does not exists
  • Request Pipeline Termination:
    • For Handler & Modules: CompleteRequest() would terminate the request
    • For ASP.NET Core: By not passing the request delegate to the next component

Points of Interest

  • We consider ASP.NET Core Middleware is compination of HTTP Handler & Module.
  • Placing of the app.Use() method at the Starup.cs configure() is key for the execution of the middleware.
  • ASP.NET Core comes with different types out-of-box of Middleware. For e.g.. Authentication, Sessions, CORS, etc.

End Note

I have placed the code on github which uses different middleware mainly sessions (In Memory) and passing of the data. The code can be found at https://github.com/psdinesh/MigratingHttpHandlersModulesAspNetCoreMiddleware.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionWrite Response does not work when used inside app.use() method Pin
Ankush Jain2-Dec-18 19:44
Ankush Jain2-Dec-18 19:44 
GeneralMessage Closed Pin
8-Apr-17 3:48
Member 131149428-Apr-17 3:48 
QuestionMessage Closed Pin
5-Jan-17 13:44
Member 129366815-Jan-17 13:44 
Message Closed
QuestionHow to address all events in global.asax file when we work with ASP.NET Core Middleware Pin
Tridip Bhattacharjee14-Dec-16 20:52
professionalTridip Bhattacharjee14-Dec-16 20:52 
AnswerRe: How to address all events in global.asax file when we work with ASP.NET Core Middleware Pin
Srinivasa Dinesh Parupalli15-Dec-16 23:47
professionalSrinivasa Dinesh Parupalli15-Dec-16 23:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.