Really wanted to get better at this myself so had some fun experimenting getting something to work. Sadly I had some troubling using .AddRedirect to also match on the querystring.
So I came up with the following solution, I hope this helps you:
var rewriteOptions = new RewriteOptions()
.Add(new RuleForU1AndU2())
.Add(new RuleForU1());
And then having 2 rules:
public class RuleForU1 : IRule
{
private int StatusCode { get; } = (int)System.Net.HttpStatusCode.MovedPermanently;
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var url = request.Path.Value;
var queryString = request.QueryString.Value;
if (!url.Equals("/details.aspx", StringComparison.OrdinalIgnoreCase) || queryString.Length == 0)
{
context.Result = RuleResult.ContinueRules;
return;
}
var regexMatches = Regex.Matches(queryString, @"^?u1=(.*)");
if(regexMatches.Count == 0)
{
context.Result = RuleResult.ContinueRules;
return;
}
string newUrl = regexMatches[0].Groups[1].Value;
var response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location] = newUrl;
context.Result = RuleResult.EndResponse;
return;
}
}
public class RuleForU1AndU2 : IRule
{
private int StatusCode { get; } = (int)System.Net.HttpStatusCode.MovedPermanently;
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var url = request.Path.Value;
var queryString = request.QueryString.Value;
if (!url.Equals("/details.aspx", StringComparison.OrdinalIgnoreCase) || queryString.Length == 0)
{
context.Result = RuleResult.ContinueRules;
return;
}
var regexMatches = Regex.Matches(queryString, @"^?u1=(.*)&u2=(.*)");
if (regexMatches.Count == 0)
{
context.Result = RuleResult.ContinueRules;
return;
}
string newUrl = $"{regexMatches[0].Groups[1].Value}/{regexMatches[0].Groups[2]}";
var response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Location] = newUrl;
context.Result = RuleResult.EndResponse;
return;
}
}
I didn't really put any effort into code reuse... and you can probably merge the 2 rules into one rule, but I don't know what your full usecase is (like will there also be a u3?) So... I hope this helps you get closer to where you need to go :)