吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 694|回复: 3
收起左侧

[经验求助] C# Winform中使用IHttpClientFactory,改如何正确携带自定义协议头和Cookie?

[复制链接]
dayan1106 发表于 2024-3-25 21:50
300吾爱币
前言
多线程里面执行高并发网络请求,原使用Httpclient进行封装,虽用using进行资源释放,但实际并未能够及时释放,且导致各种异常。

C# Winform中使用IHttpClientFactory与HttpClientFactory进行高并发网络请求,代码贴在下面,遇到的问题是无法正确携带上Cookie,现向大佬们求助。
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace HttpClientHelper
{
    public class HttpClientHelper_
    {
        private readonly IHttpClientFactory _httpClientFactory;

        public HttpClientHelper_(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task<(string responseContent, string cookie)> SendRequest(string url, string method, string data, string cookie, bool redirection = false, Dictionary<string, string> customHeaders = null, int timeoutSeconds = 50)
        {
            var httpClient = _httpClientFactory.CreateClient();

            httpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);

            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(method), url);

            // 添加自定义请求头
            if (customHeaders != null)
            {
                foreach (var header in customHeaders)
                {
                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }

            // 添加Cookie
            if (!string.IsNullOrEmpty(cookie))
            {
                request.Headers.Add(HttpRequestHeader.Cookie.ToString(), cookie);
            }

            // 如果请求方法为POST,添加请求内容  
            if (method.Equals("POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(data))
            {
                string contentType = customHeaders != null && customHeaders.ContainsKey("Content-Type") ? customHeaders["Content-Type"] : "application/x-www-form-urlencoded";
                request.Content = new StringContent(data, Encoding.UTF8, contentType);
            }

            HttpResponseMessage response = await httpClient.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                string responseContent = await response.Content.ReadAsStringAsync();
                string cookieValue = CombineAndUpdateCookie(cookie, ParseNewCookie(response.Headers.ToString()));//合并更新Cookie

                return (responseContent, cookieValue);
            }
            else
            {
                throw new HttpRequestException($"Failed to make {method} request. Status code: {response.StatusCode}");
            }
        }
        static string ParseNewCookie(string newCookieHeaders)
        {
            try
            {
                Dictionary<string, string> cookieDict = new Dictionary<string, string>();

                // 使用正则表达式匹配Set-Cookie头部并提取cookie信息
                MatchCollection matches = Regex.Matches(newCookieHeaders, @"Set-Cookie:(.*?)\r");

                foreach (Match match in matches)
                {
                    string cookieHeader = match.Groups[1].Value;

                    // 使用正则表达式匹配键和值
                    MatchCollection matches_ = Regex.Matches(cookieHeader, @"([^\s;=]+)=([^;]+)");


                    foreach (Match match_ in matches_)
                    {
                        string t = match_.Value.Trim().Replace("path=/,", "").Replace("path=/;", "").Replace("path=/", "");
                        string[] keyValue = t.Split('=');
                        if (keyValue.Length == 2)
                        {
                            string key = keyValue[0].Trim();
                            string value = keyValue[1].Trim();
                            cookieDict[key] = value;
                        }
                    }
                }



                // 将新cookie转换为字符串形式
                StringBuilder newCookie = new StringBuilder();
                foreach (var kvp in cookieDict)
                {
                    newCookie.Append(kvp.Key).Append("=").Append(kvp.Value).Append("; ");
                }

                return newCookie.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine($"解析新Cookie失败:{e.Message}  {newCookieHeaders}");
                return "";
            }

        }

        static string CombineAndUpdateCookie(string oldCookie, string newCookie)
        {
            try
            {
                // 解析旧cookie
                Dictionary<string, string> cookieDict = ParseCookie(oldCookie);

                // 解析新cookie
                Dictionary<string, string> newCookieDict = ParseCookie(newCookie);

                // 更新旧cookie中的值或添加新的cookie项
                foreach (var kvp in newCookieDict)
                {
                    cookieDict[kvp.Key] = kvp.Value;
                }

                // 将合并后的cookie重新格式化为字符串形式
                StringBuilder combinedCookie = new StringBuilder();
                foreach (var kvp in cookieDict)
                {
                    combinedCookie.Append(kvp.Key).Append("=").Append(kvp.Value).Append("; ");
                }

                return combinedCookie.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine($"合并Cookie失败:{e.Message}");
                return "";
            }
        }

        static Dictionary<string, string> ParseCookie(string cookie)
        {
            Dictionary<string, string> cookieDict = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(cookie))
            {
                try
                {
                    string[] cookieParts = cookie.Split(';', (char)StringSplitOptions.RemoveEmptyEntries);
                    foreach (string part in cookieParts)
                    {
                        string[] keyValue = part.Split('=', (char)2);
                        if (keyValue.Length == 2)
                        {
                            string key = keyValue[0].Trim();
                            string value = keyValue[1].Trim();
                            cookieDict[key] = value;
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"解析Cookie失败:{e.Message}");
                }
            }
            return cookieDict;
        }
    }
}

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
莫忘初 + 3 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Focalors 发表于 2024-3-25 21:58

以下是对C# WinForms中使用IHttpClientFactoryHttpClientFactory进行高并发网络请求时,处理自定义头和Cookie的方法的修改:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace HttpClientHelper
{
    public class HttpClientHelper_
    {
        private readonly IHttpClientFactory _httpClientFactory;

        public HttpClientHelper_(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task<(string responseContent, string cookie)> SendRequest(string url, string method, string data, string cookie, bool redirection = false, Dictionary<string, string> customHeaders = null, int timeoutSeconds = 50)
        {
            var httpClient = _httpClientFactory.CreateClient();

            httpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);

            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(method), url);

            // 添加自定义头部
            if (customHeaders != null)
            {
                foreach (var header in customHeaders)
                {
                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }

            // 添加Cookie
            if (!string.IsNullOrEmpty(cookie))
            {
                httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
            }

            // 如果请求方法为POST,添加请求内容  
            if (method.Equals("POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(data))
            {
                string contentType = customHeaders != null && customHeaders.ContainsKey("Content-Type") ? customHeaders["Content-Type"] : "application/x-www-form-urlencoded";
                request.Content = new StringContent(data, Encoding.UTF8, contentType);
            }

            HttpResponseMessage response = await httpClient.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                string responseContent = await response.Content.ReadAsStringAsync();
                string cookieValue = CombineAndUpdateCookie(cookie, ParseNewCookie(response.Headers.GetValues("Set-Cookie")));

                return (responseContent, cookieValue);
            }
            else
            {
                throw new HttpRequestException($"无法进行 {method} 请求。状态码: {response.StatusCode}");
            }
        }

        static string ParseNewCookie(IEnumerable<string> newCookieHeaders)
        {
            try
            {
                Dictionary<string, string> cookieDict = new Dictionary<string, string>();

                foreach (var cookieHeader in newCookieHeaders)
                {
                    // 使用正则表达式解析Cookie头部
                    MatchCollection matches = Regex.Matches(cookieHeader, @"([^=]+)=([^;]+);?");
                    foreach (Match match in matches)
                    {
                        string key = match.Groups[1].Value;
                        string value = match.Groups[2].Value;
                        cookieDict[key] = value;
                    }
                }

                // 将新Cookie转换为字符串形式
                StringBuilder newCookie = new StringBuilder();
                foreach (var kvp in cookieDict)
                {
                    newCookie.Append(kvp.Key).Append("=").Append(kvp.Value).Append("; ");
                }

                return newCookie.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine($"解析新Cookie失败:{e.Message}");
                return "";
            }
        }

        static string CombineAndUpdateCookie(string oldCookie, string newCookie)
        {
            try
            {
                // 解析旧Cookie
                Dictionary<string, string> cookieDict = ParseCookie(oldCookie);

                // 解析新Cookie
                Dictionary<string, string> newCookieDict = ParseCookie(newCookie);

                // 更新旧Cookie中的值或添加新的Cookie项
                foreach (var kvp in newCookieDict)
                {
                    cookieDict[kvp.Key] = kvp.Value;
                }

                // 将合并后的Cookie重新格式化为字符串形式
                StringBuilder combinedCookie = new StringBuilder();
                foreach (var kvp in cookieDict)
                {
                    combinedCookie.Append(kvp.Key).Append("=").Append(kvp.Value).Append("; ");
                }

                return combinedCookie.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine($"合并Cookie失败:{e.Message}");
                return "";
            }
        }

        static Dictionary<string, string> ParseCookie(string cookie)
        {
            Dictionary<string, string> cookieDict = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(cookie))
            {
                try
                {
                    string[] cookieParts = cookie.Split(';', StringSplitOptions.RemoveEmptyEntries);
                    foreach (string part in cookieParts)
                    {
                        string[] keyValue = part.Split('=', 2);
                        if (keyValue.Length == 2)
                        {
                            string key = keyValue[0].Trim();
                            string value = keyValue[1].Trim();
                            cookieDict[key] = value;
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"解析Cookie失败:{e.Message}");
                }
            }
            return cookieDict;
        }
    }
}

修改内容:

  1. 将Cookie添加到httpClient.DefaultRequestHeaders而不是request.Headers中。
  2. 修改了解析Set-Cookie头部的方法,以处理多个Cookie头部。
  3. 更改了从响应头中获取Set-Cookie头部的方法。
  4. 简化了Cookie头部的解析方法。

通过这些修改,应该可以正确地将Cookie包含在请求头中。确保服务器也正确处理Cookie。

 楼主| dayan1106 发表于 2024-3-25 22:20
Focalors 发表于 2024-3-25 21:58
[md]以下是对C# WinForms中使用`IHttpClientFactory`和`HttpClientFactory`进行高并发网络请求时,处理自定 ...

并未能正确携带Cookie。
WenJiaxin02 发表于 2024-3-26 08:29
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace HttpClientHelper
{
    public class HttpClientHelper_
    {
        private readonly IHttpClientFactory _httpClientFactory;

        public HttpClientHelper_(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task<(string responseContent, string cookie)> SendRequest(string url, string method, string data, string cookie, bool redirection = false, Dictionary<string, string> customHeaders = null, int timeoutSeconds = 50)
        {
            var httpClient = _httpClientFactory.CreateClient();

            httpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);

            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(method), url);

            // 添加自定义头部
            if (customHeaders != null)
            {
                foreach (var header in customHeaders)
                {
                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }
            }

            // 添加 Cookie
            if (!string.IsNullOrEmpty(cookie))
            {
                // 将 Cookie 添加到 DefaultRequestHeaders 中
                httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
            }

            // 如果请求方法为 POST,添加请求内容
            if (method.Equals("POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(data))
            {
                string contentType = customHeaders != null && customHeaders.ContainsKey("Content-Type") ? customHeaders["Content-Type"] : "application/x-www-form-urlencoded";
                request.Content = new StringContent(data, Encoding.UTF8, contentType);
            }

            HttpResponseMessage response = await httpClient.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                string responseContent = await response.Content.ReadAsStringAsync();

                // 获取响应头中的 Set-Cookie 头部
                IEnumerable<string> setCookieHeaders;
                if (response.Headers.TryGetValues("Set-Cookie", out setCookieHeaders))
                {
                    foreach (var setCookieHeader in setCookieHeaders)
                    {
                        // 解析并合并新的 Cookie
                        cookie = CombineAndUpdateCookie(cookie, ParseNewCookie(setCookieHeader));
                    }
                }

                return (responseContent, cookie);
            }
            else
            {
                throw new HttpRequestException($"无法进行 {method} 请求。状态码: {response.StatusCode}");
            }
        }

        static string ParseNewCookie(string newCookieHeader)
        {
            try
            {
                // 使用正则表达式解析 Set-Cookie 头部
                MatchCollection matches = Regex.Matches(newCookieHeader, @"([^=]+)=([^;]+);?");
                Dictionary<string, string> cookieDict = new Dictionary<string, string>();

                foreach (Match match in matches)
                {
                    string key = match.Groups[1].Value;
                    string value = match.Groups[2].Value;
                    cookieDict[key] = value;
                }

                // 将新 Cookie 转换为字符串形式
                StringBuilder newCookie = new StringBuilder();
                foreach (var kvp in cookieDict)
                {
                    newCookie.Append(kvp.Key).Append("=").Append(kvp.Value).Append("; ");
                }

                return newCookie.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine($"解析新 Cookie 头部失败:{e.Message}");
                return "";
            }
        }

        static string CombineAndUpdateCookie(string oldCookie, string newCookie)
        {
            try
            {
                // 解析旧 Cookie
                Dictionary<string, string> cookieDict = ParseCookie(oldCookie);

                // 解析新 Cookie
                Dictionary<string, string> newCookieDict = ParseCookie(newCookie);

                // 更新旧 Cookie 中的值或添加新的 Cookie 项
                foreach (var kvp in newCookieDict)
                {
                    cookieDict[kvp.Key] = kvp.Value;
                }

                // 将合并后的 Cookie 重新格式化为字符串形式
                StringBuilder combinedCookie = new StringBuilder();
                foreach (var kvp in cookieDict)
                {
                    combinedCookie.Append(kvp.Key).Append("=").Append(kvp.Value).Append("; ");
                }

                return combinedCookie.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine($"合并 Cookie 失败:{e.Message}");
                return "";
            }
        }

        static Dictionary<string, string> ParseCookie(string cookie)
        {
            Dictionary<string, string> cookieDict = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(cookie))
            {
                try
                {
                    string[] cookieParts = cookie.Split(';', StringSplitOptions.RemoveEmptyEntries);
                    foreach (string part in cookieParts)
                    {
                        string[] keyValue = part.Split('=', 2);
                        if (keyValue.Length == 2)
                        {
                            string key = keyValue[0].Trim();
                            string value = keyValue[1].Trim();
                            cookieDict[key] = value;
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"解析 Cookie 失败:{e.Message}");
                }
            }
            return cookieDict;
        }
    }
}
请测试一下并确保服务器也正确处理 Cookie
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-12 22:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表