How do I handle a .ashx Generic Handler page in Blazor?

224 Views Asked by At

I am replacing a Project built using ASP.NET WebForms and I need to replace the .ashx Generic Handlers - but I need to keep the page names so an app that has these URIs hardcoded does not require updating.

I know how to deal with the logic, that is not the problem. The problem is that these pages are referenced by an app that I do not want to update, so I need to be able to use URIs that point to pages ending in .ashx.

I have tried everything I can think of. I had hoped to just use the @page directive as shown below:

@page "/mygenerichandler.ashx"

Unfortunately, that does not work. If it did, I would be all set.

I have seen pages telling me to handle the .ashx as a sort of parameter:

@page "/mygenerichandler/{ashx}" (and variations of this, none work)

This does not work.

I have tried just naming the pages with the .ashx extension. This does not work.

I do not want to have to update the apps that have the URLs embedded in them, but it is looking more and more like that is my only option.

Is there any way to accept a page request in Blazor to a page that is named something like "mygenerichandler.ashx"?

2

There are 2 best solutions below

1
BookTrakker On

I figured it out. I am using the Middleware Pattern, and it turns out that this will execute early in the pipeline and allow me to inspect the URL for the .ashx extension and then route accordingly. I should be able to return a response from this point - I still have to implement that code, but it is not directly germane to this question so I will not cover it here.

public class HandlerTrapper
    {
        private readonly RequestDelegate _next;

        
        public string? AccountID { get; set; }

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

        public Task Invoke(HttpContext httpContext)  //, [FromQuery(Name = "AccountID")] string accountId
        {           

            string? page = httpContext.Request.Path.Value?.Replace(@"/", "");

            Console.WriteLine("Page Name is {0}, AccountID = {1}", page, AccountID);

            if(page==null || !page.Contains(".ashx"))
                return _next(httpContext);

            AccountID = httpContext.Request.Query["AccountID"];

            switch (page)
            {
                case "GetAmzRefreshToken":

                    break;
            }

            return _next(httpContext);
        }

        private 
    }

    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class HandlerTrapperExtensions
    {
        public static IApplicationBuilder UseHandlerTrapper(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<HandlerTrapper>();
        }
    }

This is called as shown here in Program.cs:


app.UseHandlerTrapper();


I am pretty sure I can just return a Response from here and after implementing the code that does the work based on the incoming legacy page name, I should have a replacement for my .ashx Generic Handlers.

0
BookTrakker On

There is an even better solution which I implemented in my code. The WebApplication class has a UrlReWriter method that solves this problem quite elegantly when used in conjunction with the Controller Routing.

I added these lines to my Program.cs file - I placed them before the UseHttpRedirection and the UseRouting calls.:

    RewriteOptions urlOptions = new RewriteOptions().AddRewrite(@"^(.*).ashx$", "api/$1", false);

    urlOptions.AddRewrite(@"^(.*).inf$", "api/ComputerInfo", false);

    app.UseRewriter(urlOptions);

That resolved the issue for both of the file type patterns I needed to handle, and I can add more if need be.