Convert Microsoft.AspNetCore.Http.HttpRequest to HttpRequestMessage

I need to convert Microsoft.AspNetCore.Http.HttpRequest from the AspNetCore context to HttpRequestMessage in order to go to HttpClient. Is there an easy way to achieve this? Or any hint of implementing this will be very helpful.

Update I want to convert the request into a message, but I want to change the destination URL, I just want to redirect the request to another server.

+5
source share
2 answers

I ended up with this:

public static class RequestTranscriptHelpers { public static HttpRequestMessage ToHttpRequestMessage(this HttpRequest req) => new HttpRequestMessage() .SetMethod(req) .SetAbsoluteUri(req) .SetHeaders(req) .SetContent(req) .SetContentType(req); private static HttpRequestMessage SetAbsoluteUri(this HttpRequestMessage msg, HttpRequest req) => msg.Set(m => m.RequestUri = new UriBuilder { Scheme = req.Scheme, Host = req.Host.Host, Port = req.Host.Port.Value, Path = req.PathBase.Add(req.Path), Query = req.QueryString.ToString() }.Uri); private static HttpRequestMessage SetMethod(this HttpRequestMessage msg, HttpRequest req) => msg.Set(m => m.Method = new HttpMethod(req.Method)); private static HttpRequestMessage SetHeaders(this HttpRequestMessage msg, HttpRequest req) => req.Headers.Aggregate(msg, (acc, h) => acc.Set(m => m.Headers.TryAddWithoutValidation(h.Key, h.Value.AsEnumerable()))); private static HttpRequestMessage SetContent(this HttpRequestMessage msg, HttpRequest req) => msg.Set(m => m.Content = new StreamContent(req.Body)); private static HttpRequestMessage SetContentType(this HttpRequestMessage msg, HttpRequest req) => msg.Set(m => m.Content.Headers.Add("Content-Type", req.ContentType), applyIf: req.Headers.ContainsKey("Content-Type")); private static HttpRequestMessage Set(this HttpRequestMessage msg, Action<HttpRequestMessage> config, bool applyIf = true) { if (applyIf) { config.Invoke(msg); } return msg; } } public static class ResponseTranscriptHelpers { public static async Task FromHttpResponseMessage(this HttpResponse resp, HttpResponseMessage msg) { resp.SetStatusCode(msg) .SetHeaders(msg) .SetContentType(msg); await resp.SetBodyAsync(msg); } private static HttpResponse SetStatusCode(this HttpResponse resp, HttpResponseMessage msg) => resp.Set(r => r.StatusCode = (int)msg.StatusCode); private static HttpResponse SetHeaders(this HttpResponse resp, HttpResponseMessage msg) => msg.Headers.Aggregate(resp, (acc, h) => acc.Set(r => r.Headers[h.Key] = new StringValues(h.Value.ToArray()))); private static async Task<HttpResponse> SetBodyAsync(this HttpResponse resp, HttpResponseMessage msg) { using (var stream = await msg.Content.ReadAsStreamAsync()) using (var reader = new StreamReader(stream)) { var content = await reader.ReadToEndAsync(); return resp.Set(async r => await r.WriteAsync(content)); } } private static HttpResponse SetContentType(this HttpResponse resp, HttpResponseMessage msg) => resp.Set(r => r.ContentType = msg.Content.Headers.GetValues("Content-Type").Single(), applyIf: msg.Content.Headers.Contains("Content-Type")); private static HttpResponse Set(this HttpResponse msg, Action<HttpResponse> config, bool applyIf = true) { if (applyIf) { config.Invoke(msg); } return msg; } } 

I have not tried @Strenkor En'Triel's answer since I first found this solution, but I will try.

0
source

Try API Compatibility API

 HttpRequestMessageFeature hreqmf = new HttpRequestMessageFeature(context); HttpRequestMessage httpRequestMessage = hreqmf.HttpRequestMessage; 

Or you can be inspired by Microsoft.AspNetCore.Proxy

These extensions for httpContext may come in handy: https://github.com/aspnet/Proxy/blob/dev/src/Microsoft.AspNetCore.Proxy/ProxyAdvancedExtensions.cs

+2
source

Source: https://habr.com/ru/post/1271001/


All Articles