I have simple url rewriter:
private static void RedirectToAPI(RewriteContext context)
{
var request = context.HttpContext.Request;
if (request.Path.Value.StartsWith("/apiendpoint", StringComparison.OrdinalIgnoreCase))
{
var json = JsonConvert.SerializeObject(request.Path.Value
.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
.Skip(1));
var response = context.HttpContext.Response;
response.Headers[HeaderNames.Location] = $"/custom";
response.StatusCode = StatusCodes.Status301MovedPermanently;
context.Result = RuleResult.EndResponse;
using (var bodyWriter = new StreamWriter(response.Body))
{
bodyWriter.Write(json);
bodyWriter.Flush();
}
}
}
The problem is, when it redirects to /custom url, request has method GET, while this method require POST.
For example, send GET request to url /apiendpoint/first/second/third, then rewriter responds to redirect, accordingly, the following request must be with method POST, but now, it is GET.
How can I change method of request, which is after url rewriter response?
This is a sample code
public class ConvertGetToPostHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Add your logic here to decide if the request Method needs to be changed
// Caution: This works only if you're redirecting internally
request.Method = HttpMethod.Post;
return await base.SendAsync(request, cancellationToken);
}
}
You will have to add the Handler to Handler Pipeline as
config.MessageHandlers.Add(new ConvertGetToPostHandler());
Also, read over this documentation to get some insight into it's purpose and usage.
Can you set @juunas answer as a correct answer, his answer solved it for me as you can see in my example code.
internal class RedirectCultureRule : IRule
{
private const string CultureKey = "culture";
public void ApplyRule(RewriteContext context)
{
HttpRequest httpRequest = context.HttpContext.Request;
httpRequest.Query.TryGetValue(CultureKey, out StringValues cultureValues);
string culture = cultureValues;
if (cultureValues.Count > 0 && culture.IsCultureMatch())
{
context.Result = RuleResult.ContinueRules;
return;
}
Dictionary<string, string> queryParts = new Dictionary<string, string>();
NameValueCollection queryString = HttpUtility.ParseQueryString(httpRequest.QueryString.ToString());
foreach (string key in queryString)
{
queryParts[key.Trim()] = queryString[key].Trim();
}
if (!queryParts.ContainsKey(CultureKey))
{
queryParts[CultureKey] = CultureInfo.CurrentCulture.Name;
}
string query = $"?{string.Join("&", queryParts.Select(qp => $"{qp.Key}={qp.Value}"))}";
if (query.Length > 1)
{
httpRequest.QueryString = new QueryString(query);
}
string url = UriHelper.GetDisplayUrl(httpRequest);
HttpResponse httpResponse = context.HttpContext.Response;
httpResponse.StatusCode = 308;
httpResponse.Headers[HeaderNames.Location] = url;
using (StreamReader requestReader = new StreamReader(httpRequest.Body))
{
using (StreamWriter responseWriter = new StreamWriter(httpResponse.Body))
{
string body = requestReader.ReadToEnd();
responseWriter.Write(body);
responseWriter.Flush();
}
}
context.Result = RuleResult.EndResponse;
}
}
If using ASP.NET Core 2.0 there is RedirectPermanentPreserveMethod, you can read about it here. If this method is not supported you can try doing it manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With