Search code examples
c#httpasp.net-core-mvcmiddlewarelaravel-middleware

How to allow user to create a redirect from one URL to another URL


I am trying to allow a user (these would only be admin) to redirect one URL to another URL (I own all of these URLs so I am able to redirect them). I am currently passing the URLs they enter from the view to the controller but I am unable to figure out how I can pass this data from my controller to my middleware.

In my controller I tried to use the HttpContext.Items dictionary to set the values for the incoming url and the outgoing url which looks like so.

public IActionResult RedirectFromView(string userIncomingUrl, string userOutgoingUrl)
{
    HttpContext.Items["incomingUrl"] = userIncomingUrl;
    HttpContext.Items["outgoingUrl"] = userOutgoingUrl;

    return RedirectToAction("Index");
}

Now I know when it comes to creating middleware that the pipeline is important, in my program.cs file I have made the following:

app.UseStaticFiles();
app.UseMiddleware<RedirectFromView>("/userIncomingUrl", "/userOutgoingUrl");
app.UseHttpsRedirection();
app.UseRouting();
app.UseSession();
app.UseAuthorization();

Finally, in my middleware I am trying to perform the redirect like this:

public class RedirectFromView
{
    private readonly RequestDelegate _next;
    private readonly string _incomingUrl;
    private readonly string _outgoingUrl;

    public RedirectFromView(RequestDelegate next, string incomingUrl, string outgoingUrl)
    {
        _next = next;
        _incomingUrl = incomingUrl;
        _outgoingUrl = outgoingUrl;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        //Validate url trying to be hit by user
        var UrlBeingHit = context.Request.GetDisplayUrl();
        if (UrlBeingHit.Contains == _incomingUrl)
        {
              context.Response.Redirect(_outgoingUrl)
        }
        await _next(context);
    }
}

I must be taking the complete wrong approach when passing data from my controller to middleware. Please note that I am successfully getting the data from my view to the controller. The problem lies when passing the data from the controller to my middleware.


Solution

  • From your description of this question. I think the scenario you want to achieve is there is a view in your project in your project. After user input the incomingUrl and outgoingUrl and submit the form, Later request to incomingUrl will be redirected to outgoingUrl automatically via middleware.

    If I don't misunderstand your question, Here is a working demo, Hope it can help you solve this issue.

    controller

    [HttpPost]
            public IActionResult Set(string userIncomingUrl, string userOutgoingUrl)
            {
                //Here i use session to save the url, you can also save it into database
    
                HttpContext.Session.SetString("incomingUrl", userIncomingUrl);
                HttpContext.Session.SetString("outgoingUrl", userOutgoingUrl);
                return RedirectToAction("Index");
            }
    

    MiddleWare

    public class MyMiddleware
        {
            private readonly RequestDelegate _next;
    
            public MyMiddleware(RequestDelegate next)
            {
                _next = next;
            }
    
            public async Task InvokeAsync(HttpContext context)
            {
                var incomingUrl = context.Session.GetString("incomingUrl");
                var outgoingUrl = context.Session.GetString("outgoingUrl");
    
                var originalUrl = context.Request.GetDisplayUrl();
    
                if (incomingUrl!=null)
                {
                    // Retrieve the data from HttpContext.Items
                    if (originalUrl.Contains(incomingUrl))
                    {
                        context.Response.Redirect(outgoingUrl);
                    }
                }
    
                // Call the next middleware in the pipeline
                await _next(context);
            }
        }
    

    Gif Demo

    enter image description here

    From above demo, You can find when I first access privacy page, it can access successfully, But after I set Privacy as incomingUrl and /Home/new as outgoingUrl in Set page, When I access Privacy page again, It will redirect to new page automatically.