【问题标题】:Is there a more elegant/clean way to set HttpRequestMessage Headers using TryAddWithoutValidation method?有没有更优雅/干净的方法来使用 TryAddWithoutValidation 方法设置 HttpRequestMessage 标头?
【发布时间】:2023-03-07 14:07:01
【问题描述】:

我在几个方法中使用来自 HttpClient 的 HttpRequestMessage,目前,我在我的代码中重复以下代码:

此代码由https://curl.olsh.me/ 转换,因此我不确定此处是否使用了最佳做法。

// using System.Net.Http;
using (var httpClient = new HttpClient(handler))
 {
     using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://www.url.com/"))
                {
                    request.Headers.TryAddWithoutValidation("authority", "www.url.com");
                    request.Headers.TryAddWithoutValidation("pragma", "no-cache");
                    request.Headers.TryAddWithoutValidation("cache-control", "no-cache");
                    request.Headers.TryAddWithoutValidation("dnt", "1");
                    request.Headers.TryAddWithoutValidation("x-requested-with", "XMLHttpRequest");
                    request.Headers.TryAddWithoutValidation("x-odesk-csrf-token", "19b91748869456a4ae700ffb69077745");
                    request.Headers.TryAddWithoutValidation("user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36");
                    request.Headers.TryAddWithoutValidation("accept", "*/*");
                    request.Headers.TryAddWithoutValidation("origin", "https://www.url.com");
                    request.Headers.TryAddWithoutValidation("sec-fetch-site", "same-origin");
                    request.Headers.TryAddWithoutValidation("sec-fetch-mode", "cors");
                    request.Headers.TryAddWithoutValidation("sec-fetch-dest", "empty");
                    request.Headers.TryAddWithoutValidation("referer", "https://www.url.com/");
                    request.Headers.TryAddWithoutValidation("accept-language", "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,fr-FR;q=0.6,fr;q=0.5");
                    request.Headers.TryAddWithoutValidation("cookie", "G_AUTHUSER_H=1; AccountSecurity_cat=fc4d14f1.oauth2v2_812293");
                    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                    var response = await httpClient.SendAsync(request);

                    IEnumerable<string> cookies = new List<string>();
                    response.Headers.TryGetValues("Set-Cookie", out cookies);

【问题讨论】:

    标签: c# .net-core dotnet-httpclient http-method


    【解决方案1】:

    我假设您正在尝试了解如何将相关代码提取到辅助方法中,因为它使用了 using 块。如果没有,请澄清,我会调整我的答案。在这种情况下,我会这样做:

    Task<HttpResponseMessage> PostAsyncWithHeaders(Uri uri)
    {
        var response = new Task<HttpResponseMessage>();
    
        using (var httpClient = new HttpClient(handler))
        using (var request = new HttpRequestMessage(HttpMethod.Post, uri))
        {
            //Add your headers as before
    
            response = await httpClient.SendAsync(request);
        }
    
        return response;
    }
    

    然后您可以从任何可以访问的地方调用该方法,如下所示:

    response = await PostAsyncWithHeaders(new Uri("https://www.url.com/"));
    
    IEnumerable<string> cookies = new List<string>();
    response.Headers.TryGetValues("Set-Cookie", out cookies);
    //Presumably consume cookies (yum!)
    

    【讨论】:

      【解决方案2】:

      我在 .NET Core 3 中做了这个测试以供参考。

      如果您希望能够在整个代码库中重用您的方法,您可以尝试以下方法:

       static async Task Main(string[] args)
          {
              var client = new HttpClient();
      
              // .NET core setting the content type.
              client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
      
              // this is wrapped in the using statement.
              using var requestMessage = GetRequestMessage("https://www.url.com/", HttpMethod.Post);
              await client.SendAsync(requestMessage);
          }
      
          // Get the request message for reuse. You can then reuse this for maybe different end-points and method types. 
          // the "referer" or "origin" values can be passed in as parameters too. 
          static HttpRequestMessage GetRequestMessage(string url, HttpMethod method)
          {
              var request = new HttpRequestMessage(method, url);
      
              request.Headers.TryAddWithoutValidation("authority", "www.url.com");
              request.Headers.TryAddWithoutValidation("pragma", "no-cache");
              request.Headers.TryAddWithoutValidation("cache-control", "no-cache");
              request.Headers.TryAddWithoutValidation("dnt", "1");
              request.Headers.TryAddWithoutValidation("x-requested-with", "XMLHttpRequest");
              request.Headers.TryAddWithoutValidation("x-odesk-csrf-token", "19b91748869456a4ae700ffb69077745");
              request.Headers.TryAddWithoutValidation("user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36");
              request.Headers.TryAddWithoutValidation("accept", "*/*");
              request.Headers.TryAddWithoutValidation("origin", "https://www.url.com");
              request.Headers.TryAddWithoutValidation("sec-fetch-site", "same-origin");
              request.Headers.TryAddWithoutValidation("sec-fetch-mode", "cors");
              request.Headers.TryAddWithoutValidation("sec-fetch-dest", "empty");
              request.Headers.TryAddWithoutValidation("referer", "https://www.url.com/");
              request.Headers.TryAddWithoutValidation("accept-language", "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,fr-FR;q=0.6,fr;q=0.5");
              request.Headers.TryAddWithoutValidation("cookie", "G_AUTHUSER_H=1; AccountSecurity_cat=fc4d14f1.oauth2v2_812293");
              
              return request;
          }
      

      如果您在控制台程序中使用它,您可以在 using 语句中创建 HttpClient。但是,如果您打算在 .net 核心中的 Web 应用程序中使用客户端,则需要使用 services.AddHttpClient 方法和依赖注入。这是因为 HttpClient 并不打算在每次使用后都被丢弃,尤其是在给定调用中多次使用它时。

      【讨论】:

        【解决方案3】:

        非常感谢@Jaquez 和@Kuroiyatsu 的回答,我得到以下答案

         public async Task<string> postAsync(param1, param2)
        {
            using (var httpClient = new HttpClient(handler))
            {
                using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://www.url.com/"))
                {
        
        ....
        
        var response = await PostAsync(param1, param2);
        
        var variable = JsonSerializer.Deserialize<Obj>(response);
        
        WebScrapFunc(response);
        
        ...
        

        虽然从 PostAsync 返回 Task&lt;string&gt; 看起来很奇怪,但它符合我的意图。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-28
          相关资源
          最近更新 更多