目录
  • 一,授权认证
    • 1. 基础认证示例
    • 2. JWT 认证示例
    • 3. Cookie 示例
  • 二,请求类型
    • 三,数据传输
      • 1. Query
      • 2. Header
      • 3. 表单
      • 4. JSON
      • 5. 上传文件

    一,授权认证

    客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 Basic 、JWT、Cookie。

    HttpClient 是 C# 中的 HTTP/HTTPS 客户端,用于发送 HTTP 请求和接收来自通过 URI 确认的资源的 HTTP 响应。下面以具体代码做示范。

    1. 基础认证示例

            // Basic基础认证
            public async Task Basic(string user, string password, string url)
            {
                // 如果认证页面是 https 的,请参考一下 jwt 认证的 HttpClientHandler
                // 创建  client 
                HttpClient client = new HttpClient();
    
                // 创建身份认证
                // using System.Net.Http.Headers;
                AuthenticationHeaderValue authentication = new AuthenticationHeaderValue(
                    "Basic",
                    Convert.ToBase64String(Encoding.UTF8.GetBytes($"{user}:{password}")
                    ));
    
    
                client.DefaultRequestHeaders.Authorization = authentication;
    
                byte[] response = await client.GetByteArrayAsync(url);
                client.Dispose();
            }

    可以看到 Basic 认证的安全程度非常低,多用于路由器和嵌入式设备,而且往往不会使用 HTTPS。

    2. JWT 认证示例

            // Jwt认证
            public async Task Bearer(string token, string url)
            {
                // HttpClientHandler及其派生类使开发人员能够配置各种选项, 包括从代理到身份验证。
                // helpLink https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler?view=netframework-4.8
                var httpclientHandler = new HttpClientHandler();
    
                // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
                // => 也就是说,不校验证书,直接允许
                httpclientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true;
    
                using (var httpClient = new HttpClient(httpclientHandler))
                {
                    // 创建身份认证
                    // System.Net.Http.Headers.AuthenticationHeaderValue;
                    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                    await httpClient.GetAsync(url);
                    httpClient.Dispose();
                }
            }

    JWT 认证,需要客户端携带 token ,token 是一段加密过的字符串,关于原理这里不多说,token 是通过客户端 header 携带的。

    另外,对于测试的 Web 应用或者内网应用, HTTPS 证书可能不是公网国际认证的证书,就需要跳过认证,直接允许访问使用。

                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                };

    3. Cookie 示例

    HttpClient 中,Cookie 有两种处理方式。

    一种是已经知道 Cookie ,直接将 Cookie 存储到 HttpClient 中;另一种是还没有 Cookie ,通过账号密码登录获取到 Cookie ,自动存储到 HttpClient 对象中,接着使用当前 HttpClient 对象请求 URL。

    两种方式的设定,是通过 HttpClientHandler 的 UseCookies 属性设置的。

    示例

                var httpclientHandler = new HttpClientHandler()
                {
                    UseCookies = true
                };

    ​ UseCookies 获取或设置一个值,该值指示处理程序是否使用 CookieContainer 属性存储服务器 Cookie,并在发送请求时使用这些 Cookie。

    方式1:

            // 先用账号密码登陆再请求
            public async Task Cookie(string user, string password, string loginUrl, string url)
            {
                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                    UseCookies = true
                };
                // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
                // => 也就是说,不校验证书,直接允许
    
                var loginContent = new FormUrlEncodedContent(new[]
                {
                 new KeyValuePair<string,string>("user",user),
                 new KeyValuePair<string, string>("password",password)
                });
                using (var httpClient = new HttpClient(httpclientHandler))
                {
                    // 先登陆
                    var result = await httpClient.PostAsync(loginUrl, loginContent);
                    // 登陆成功后,客户端会自动携带 cookie ,不需要再手动添加
                    //if (result.IsSuccessStatusCode)
                    //{
                    //    /*
                    //     * 如果请求成功
                    //     */
                    //}
    
                    var result2 = await httpClient.GetAsync(url);
                    // httpclient 已经携带 Cookie ,可以多次使用
                    // var result3 = await httpClient.GetAsync(url3);
                    // var result4 = await httpClient.GetAsync(url4);
                    httpClient.Dispose();
                }
            }

    方式2:

            //已经拿到 cookie ,直接使用 cookie 请求
            public async Task Cookie(string cookie, string url)
            {
                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                    UseCookies = false
                };
                // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
                // => 也就是说,不校验证书,直接允许
    
    
                using (var httpClient = new HttpClient(httpclientHandler))
                {
                    httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
                    await httpClient.GetAsync(url);
                    httpClient.Dispose();
                }
            }

    二,请求类型

    HTTP 请求里,有 GET、POST、DELETE、PUT 等请求方式。

    HttpClient 中,有以下请求相关的方法

    • CancelPendingRequests
    • DeleteAsync
    • GetAsync
    • GetByteArrayAsync
    • GetStreamAsync
    • GetStringAsync
    • PostAsync
    • PutAsync
    • SendAsync

    其中, CancelPendingRequests 是取消该实例所有挂起的请求,不是请求类型。

    SendAsync 用于处理送 HttpRequestMessage(表示一条 HTTP 请求消息),比较原生。

    C#客户端HttpClient请求认证及数据传输

    对于 GetAsync、PostAsync等请求方法,使用过程类似,下面是使用示例

            public async void Request(string url)
            {
    
                using (var httpClient = new HttpClient())
                {
                    // HttpClient 中,所有 Get 请求都是异步的
                    HttpResponseMessage result = await httpClient.GetAsync(url);
    
                    // Task<>.Result 可以获取异步结果
                    result = httpClient.GetAsync(url).Result;
    
                    //var result1 = await httpClient.GetByteArrayAsync(url);
                    //var result1 = await httpClient.GetStreamAsync(url);
                    //var result1 = await httpClient.GetStringAsync(url);
    
                    // ByteArrayContent
    
                    FormUrlEncodedContent fromContent = new FormUrlEncodedContent(new[]
                    {
                        new KeyValuePair<string,string>("Email","123@qq.com"),
                        new KeyValuePair<string, string>("Number","666")
                    });
                    // 使用 Post ,必须携带 继承 HttpContent 的对象
                    // 就是说,Post 必须要上传数据
                    result = await httpClient.PostAsync(url, fromContent);
    
                    // 如果没有数据要上传,可以使用 null
                    result = await httpClient.PostAsync(url, null);
    
    
                    httpClient.Dispose();
                }

    三,数据传输

    HTTP/HTTPS 请求中,往往随着数据传输,例如表单提交、JSON上传、文件上传等,下面以代码示范。

    1. Query

    ASP.NET Core API 可以这样写

            [HttpPost("aaa")]
            public async Task<JsonResult> AAA(int? a, int? b)
            {
                if (a == null || b == null)
                    return new JsonResult(new { code = 0, result = "aaaaaaaa" });
                return new JsonResult(new { code = 2000, result = a + "|" + b });
            }

    HttpClient

            // URL Query 参数
            public void Query(string a, string b)
            {
                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                };
                using (var httpClient = new HttpClient(httpclientHandler))
                {
    
                    var result = httpClient.PostAsync($"https://localhost:5001/test?a={a}&b={b}", null).Result;
    
                    httpClient.Dispose();
                }
            }

    2. Header

    Header 是以键值形式存储的,HttpClient 示例

            // Header 头
            public void Header()
            {
                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                };
                using (var httpClient = new HttpClient(httpclientHandler))
                {
                    httpClient.DefaultRequestHeaders.Add("MyEmail", "123@qq.com");
                    var result = httpClient.GetAsync($"https://localhost:5001/test").Result;
    
                    httpClient.Dispose();
                }
            }

    ASP.NET Core API 示例

            [HttpPost("ddd")]
            public async Task<JsonResult> DDD([FromHeader]int? a, [FromHeader]int? b)
            {
                if (a == null || b == null)
                    return new JsonResult(new { code = 0, result = "aaaaaaaa" });
                return new JsonResult(new { code = 200, result = a + "|" + b });
            }

    3. 表单

            //  表单提交
            // application/x-www-form-urlencoded
            public void From()
            {
                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                };
    
                var fromContent = new FormUrlEncodedContent(new[]
                {
                 new KeyValuePair<string,string>("Id","1"),
                 new KeyValuePair<string,string>("Name","痴者工良"),
                 new KeyValuePair<string, string>("Number","666666")
                });
    
                using (var httpClient = new HttpClient(httpclientHandler))
                {
                    var result = httpClient.PostAsync("https://localhost:5001/test", fromContent).Result;
    
                    Console.WriteLine(result.Content.ReadAsStringAsync().Result);
                    httpClient.Dispose();
                }
            }

    4. JSON

    除了 JSON ,还有

    • text/html
    • application/javascript
    • text/plain
    • application/xml

    他们都是使用 StringContent 来表示。

            // Json 等
            public void StringAnd(string json)
            {
                var httpclientHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                };
    
    
                var jsonContent = new StringContent(json);
    
                // Json 是 StringContent,上传时要指定 Content-Type 属性,除此外还有
                // text/html
                // application/javascript
                // text/plain
                // application/xml
                jsonContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
    
                using (var httpClient = new HttpClient(httpclientHandler))
                {
    
                    var result = httpClient.PostAsync("https://localhost:5001/test", jsonContent).Result;
    
                    Console.WriteLine(result.Content.ReadAsStringAsync().Result);
                    httpClient.Dispose();
                }
            }

    5. 上传文件

    API 这样写

          [HttpPost]    //上传文件是 post 方式,这里加不加都可以
            public async Task<IActionResult> UploadFiles(List<IFormFile> files)
            {
            // ...
            }

    HttpClient 写法

            // 上传文件
            public async Task File(string filepath, string fromName, string url)
            {
                using (var client = new HttpClient())
                {
                    FileStream imagestream = System.IO.File.OpenRead(filepath);
                    // multipartFormDataContent.Add();
                    var multipartFormDataContent = new MultipartFormDataContent()
                    {
                        {
                            new ByteArrayContent(System.IO.File.ReadAllBytes(filepath)),    // 文件流
                            fromName,                                                       // 对应 服务器 WebAPI 的传入参数
                            Path.GetFileName(filepath)                                      // 上传的文件名称
                        }
                    };
                    /* 
                     * 如果服务器 API 写法是
                     * ([FromForm]IFromFile files)
                     * 那么上面的 fromName="files"
                     */
                    // multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
    
                    HttpResponseMessage response = await client.PostAsync(url, multipartFormDataContent);
                    if (!response.IsSuccessStatusCode)
                    {
    
                        Console.WriteLine("up image error");
                        Console.WriteLine(response.RequestMessage);
                    }
                }
            }

     以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。