1

Seems like this should be a straightforward question, but I've been unable to find a solution via Google.

It seems pretty standard that in ASP.NET Core, IHttpHandler implementors are replaced by middleware classes. One nicety of the old system was that you could set up an HTTP handler to respond to a route, specified in the web.config.

So, for instance, if my IHttpHandler implementor was named FooHandler, web.config would contain something like:

<location path="foo">
    <system.webServer>
        <handlers>
            <add name="FooHandler" path="*" verb="*" type="FooCompany.FooProduct.FooHandler, FooCompany.FooProduct"/>
        </handlers>
    </system.webServer>
</location>

Is there a one-to-one replacement for routing like this in ASP.NET Core? How do I do this?

Edit: The new middleware class might look something like:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace FooCompany.FooProduct.Middleware
{
    public class FooMiddleware
    {
        private readonly RequestDelegate _next;

        public FooMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            context.Response.StatusCode = 200;
            await context.Response.WriteAsync("OK");

            await _next.Invoke(context);
        }
    }

    public static class FooMiddlewareExtensions
    {
        public static IApplicationBuilder UseFoo(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<FooMiddleware>();
        }
    }
}
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Brian Gradin
  • 2,165
  • 1
  • 21
  • 42
  • You can use Map extension method of `IApplicationBuilder` like `builder.Map("/path", b => b.UseMiddleware())` – Kalten Dec 14 '17 at 23:49

1 Answers1

4

You can use Map extension method of IApplicationBuilder like that :

public static class FooMiddlewareExtensions
{
    public static IApplicationBuilder UseFoo(this IApplicationBuilder builder, string path)
    {
        return builder.Map(path, b => b.UseMiddleware<FooMiddleware>());
    }
}

You can also do it inside your Middleware

public class FooMiddleware
{
    private readonly RequestDelegate _next;
    private readonly PathString _path;

    public FooMiddleware(RequestDelegate next, PathString path)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (!context.Request.Path.StartsWithSegments(path))
        {
            // jump to the next middleware
            await _next.Invoke(context);
        }

        // do your stuff
    }
}
Kalten
  • 4,092
  • 23
  • 32
  • Other than path is not assigned to _path and used afterwards, in .Net Core 3.0 it throws an exception in the extension method: System.InvalidOperationException: 'Unable to resolve service for type 'Microsoft.AspNetCore.Http.PathString' while attempting to activate 'FooMiddleware'. What might be missing? – PepitoSh Mar 15 '19 at 06:07
  • At least, I think you can use `app.Use(new FooMiddleware(next, "/mypath").Invoke);`. But I didn't test it on netcroe 3 – Kalten Mar 15 '19 at 09:59