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.
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
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.