使用C# 发送不同信息格式的http请求

(22) 2024-03-20 10:01:01

1.最常见的post json

 var jsonObject = JsonConvert.SerializeObject(model);
...
                        var str = new StringContent(jsonObject, Encoding.UTF8, "application/json");
...

2. url encoded content格式

...
 var formContent = new FormUrlEncodedContent(new[]
                            {
                                new KeyValuePair<string, string>("k1", "v1"),
                                new KeyValuePair<string, string>("k2", "v2")
                            });

                            var request = new HttpRequestMessage
                            {
                                Content = formContent,
                                Method = HttpMethod.Post,
                                RequestUri = new Uri(url)
                            };
 var ret = httpClient.SendAsync(request).Result;

也可以使用以下辅助函数来完成

private static TRes ApiCallAsFormData<TRes>(string url, IEnumerable<KeyValuePair<string, string>> data)
        {
            try
            {
                using (var httpClient = new HttpClient())
                {
                    var formContent = new FormUrlEncodedContent(data);

                    var ret = httpClient.PostAsync(url, formContent).Result;
                    var jsonRet = ret.Content.ReadAsStringAsync().Result;
                    return JsonConvert.DeserializeObject<TRes>(jsonRet);
                }
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                return default(TRes);
            }
        }
...

3. 发送其他 http 请求类型 (PUT,DELETE,PATCH)

...
 var request = new HttpRequestMessage
                                {
                                    Method = HttpMethod.Delete,
                                    RequestUri = new Uri($"url")
                                };
var ret = httpClient.SendAsync(request).Result;
...

3.post文件,multiplart类型
可使用以下helper类完成(可传递oauth token或cookie)

public class FormUploadHelper
    {
        private static readonly Encoding encoding = Encoding.UTF8;


        public static HttpWebResponse MultipartFormDataPost(string postUrl,
            string userAgent,
            Dictionary<string, object> postParameters, string token, IList<Cookie> cookies = null)
        {
            string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
            string contentType = "multipart/form-data; boundary=" + formDataBoundary;

            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);

            return PostForm(postUrl, userAgent, contentType, formData, token, cookies);
        }

        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType,
            byte[] formData, string token, IList<Cookie> cookies)
        {
            HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

            if (request == null)
            {
                throw new NullReferenceException("request is not a http request");
            }

            // Set up the request properties.
            request.Method = "POST";
            request.ContentType = contentType;
            if (!string.IsNullOrEmpty(token))
            {
                request.Headers.Add("accessToken", token);
            }

            if (cookies != null && cookies.Count > 0)
            {
                if (request.CookieContainer == null)
                {
                    request.CookieContainer = new CookieContainer();
                }
                foreach (var cookie in cookies)
                {
                    request.CookieContainer.Add(cookie);
                }
            }
            else
            {
                request.CookieContainer = new CookieContainer();
            }

            request.UserAgent = userAgent;
            
            request.ContentLength = formData.Length;

            // You could add authentication here as well if needed:
            // request.PreAuthenticate = true;
            // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
            // request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("username" + ":" + "password")));

            // Send the form data to the request.
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(formData, 0, formData.Length);
                requestStream.Close();
            }

            return request.GetResponse() as HttpWebResponse;
        }

        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
        {
            Stream formDataStream = new System.IO.MemoryStream();
            bool needsCLRF = false;

            if (postParameters != null)
            {
                foreach (var param in postParameters)
                {
                    // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
                    // Skip it on the first parameter, add it to subsequent parameters.
                    if (needsCLRF)
                        formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));

                    needsCLRF = true;

                    if (param.Value is FileParameter)
                    {
                        FileParameter fileToUpload = (FileParameter)param.Value;

                        // Add just the first part of this param, since we will write the file data directly to the Stream
                        string header = string.Format(
                            "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
                            boundary,
                            param.Key,
                            fileToUpload.FileName ?? param.Key,
                            fileToUpload.ContentType ?? "application/octet-stream");

                        formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));

                        // Write the file data directly to the Stream, rather than serializing it to a string.
                        formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
                    }
                    else
                    {
                        string postData = string.Format(
                            "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                            boundary,
                            param.Key,
                            param.Value);
                        formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
                    }
                }
            }

            // Add the end of the request.  Start with a newline
            string footer = "\r\n--" + boundary + "--\r\n";
            formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

            // Dump the Stream into a byte[]
            formDataStream.Position = 0;
            byte[] formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            return formData;
        }
    }

4.请求中携带cookie
获取cookie

 using (var handler = new HttpClientHandler())
                {
                    using (var httpClient = new HttpClient(handler))
                    {
...
 CookieContainer cookies = new CookieContainer();
                        handler.CookieContainer = cookies;
...
 HttpResponseMessage authenticationResponse = httpClient.PostAsync(uri, str).Result;
                        var sessionCookie = cookies.GetCookies(uri).Cast<Cookie>().ToList();
...
}
}

发送cookie
 

using (var handler = new HttpClientHandler())
                        {
                            using (var httpClient = new HttpClient(handler))
                            {
...
...
                                    foreach (var cookie in __sessionCookie)
                                    {
                                        handler.CookieContainer.Add(cookie);
                                    }
...

5. http 长连接异步逐行解析

using (HttpWebResponse webResponse = req.GetResponse(uri))
                        using (Stream responseStream = webResponse.GetResponseStream())
                        {
                            if (responseStream != null)
                            {
                                using (StreamReader streamReader = new StreamReader(responseStream))
                                {
                                    while (!streamReader.EndOfStream)
                                    {
                                        response = await streamReader.ReadLineAsync();
                                        ...
                                    }
                                }
                            }
                        }
    

 

THE END

发表回复