Convert Microsoft.AspNetCore.Http.HttpRequest to HttpRequestMessage

后端 未结 3 1925
余生分开走
余生分开走 2021-02-02 09:37

I need to convert Microsoft.AspNetCore.Http.HttpRequest from an AspNetCore context to an HttpRequestMessage to pass to an HttpClient. Is there

相关标签:
3条回答
  • 2021-02-02 10:00

    Both IHttpRequestMessageFeature and Microsoft.AspNetCore.Proxy are discontinued. IHttpRequestMessageFeature has been removed since ASP.NET Core 3.0.

    Microsoft now has a new reverse proxy nuget package Microsoft.ReverseProxy based on ASP.NET Core infrastructure. As per their docs, IHttpProxy for direct proxying scenario can:

    serve as the core proxy adapter between incoming AspNetCore and outgoing System.Net.Http requests. It handles the mechanics of creating a HttpRequestMessage from a HttpContext, sending it, and relaying the response.

    Here is an example.

    0 讨论(0)
  • 2021-02-02 10:08

    Try Web API Compatibility Shim

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

    Or you could get inspired by Microsoft.AspNetCore.Proxy

    These extensions to httpContext may come in handy.

    0 讨论(0)
  • 2021-02-02 10:09

    I ended up doing 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 haven't tried @Strenkor En'Triel response since I found this solution first, but I will try it.

    0 讨论(0)
提交回复
热议问题