软件编程
位置:首页>> 软件编程>> C#编程>> C#客户端HttpClient请求认证及数据传输

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

作者:痴者工良  发布时间:2023-06-11 21:11:00 

标签:C#,HttpClient,请求,认证,数据,传输

一,授权认证

客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 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);
               }
           }
       }

来源:https://www.cnblogs.com/whuanle/p/11656734.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com