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 中,有以下请求相关的方法

  1. CancelPendingRequests
  2. DeleteAsync
  3. GetAsync
  4. GetByteArrayAsync
  5. GetStreamAsync
  6. GetStringAsync
  7. PostAsync
  8. PutAsync
  9. SendAsync

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

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

对于 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);
}
}
}

C# HttpClient 请求认证、数据传输笔记的更多相关文章

  1. httpclient请求方法

    /** * httpclient请求方法 * @param url 请求地址 * @param paramMap 请求参数 * @param ent 编码格式 gbk.utf-8 * @return ...

  2. HttpClient请求服务器代码优化版

    HttpClient请求服务器代码优化版 首先,我在前面的两篇博文中介绍了在 Android中,除了使用java.net包下HttpUrlConnection的API访问HTTP服务之外,我们还可以换 ...

  3. 通过HttpClient请求webService

    通过HttpClient请求webService 由于服务端是用webService开发的,android要调用webService服务获取数据,这里采用的是通过HttpClient发送post请求, ...

  4. SpringMVC获取HttpClient 请求的数据

    package com.nnk.upstream.controller;import org.springframework.util.StreamUtils;import javax.servlet ...

  5. .NET 请求认证之access-token(oauth2.0与owin的结合)

    公司对外开放的接口,大多需要请求认证,如微信,阿里等.最近我刚好在搭建webapi框架.记录一下自己的理解. 一:请求认证的目的   之所以要对我们的接口进行请求认证,就是为了安全考虑的.以前都是在用 ...

  6. .NetCore简单封装基于IHttpClientFactory的HttpClient请求

    IHttpClientFactory是什么?为什么出现了IHttpClientFactory 一.IHttpClientFactory是什么? IHttpClientFactory是.netcore2 ...

  7. .NET Core HttpClient请求异常详细情况分析

    前言 最近项目上每天间断性捕获到HttpClient请求异常,感觉有点奇怪,于是乎观察了两三天,通过日志以及对接方沟通确认等等,查看对应版本源码,尝试添加部分配置发布后,观察十几小时暂无异常情况出现, ...

  8. android菜鸟学习笔记24----与服务器端交互(一)使用HttpURLConnection和HttpClient请求服务端数据

    主要是基于HTTP协议与服务端进行交互. 涉及到的类和接口有:URL.HttpURLConnection.HttpClient等 URL: 使用一个String类型的url构造一个URL对象,如: U ...

  9. HttpClient请求详解

    HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建 ...

随机推荐

  1. Python工作好找吗?没有工作经验和学历怎么找?【就业必学】

    大家都知道,随着人工智能时代的到来,Python的需求也变的越来越大了.从目前各大IT招聘网上显示招聘需求是非常大,而且薪资基本都在10k起,高的可达40-50k,当然这个要求很高,看下普遍的吧: 一 ...

  2. Linux配置免密登陆

    可能很多新手在配置免密登陆的时候第一次会经常没有配成功,会报错. 在这里将为大家演示最简洁且能一次配置成功的教程 首先以3台机器为例: 192.168.3.102 master 192.168.3.1 ...

  3. [20191218]降序索引疑问4.txt

    [20191218]降序索引疑问4.txt --//前几天优化一个项目,我发现许多表里面有有隐含字段,一般开发很少建立函数索引.我自己检查发现里面存在大量的降序索引.--//我感觉有点奇怪,为什么开发 ...

  4. centos7搭建ftp服务器并配置匿名用户

    什么是FTP? FTP(File Transfer Protocol,文件传输协议),是TCP/IP网络和Internet上最早使用的协议之一.用来将实现从一台电脑传送文件到另一台电脑,或者接收和查看 ...

  5. uiautomatorviewer提示Unable to connect to adb. Check if adb is installed correctly解决方法

    转自:https://www.jianshu.com/p/c8581a70d1bc 解决方案: 1.打开  "E:\android-sdk_r24.4.1-windows\android-s ...

  6. jQuery使用工具集

    //jq-util.js$.extend({ Util:{ /* 浏览器 */ browser:{ IE: !!document.all, IE6: !!document.all && ...

  7. 【译】浅谈SOLID原则

    SOLID原则是一种编码的标准,为了避免不良设计,所有的软件开发人员都应该清楚这些原则.SOLID原则是由Robert C Martin推广并被广泛引用于面向对象编程中.正确使用这些规范将提升你的代码 ...

  8. 工厂模式-C#改良实现

    参考了下网上的工厂模式实现,总的来说例子还是OK得,但是示例太单一了,因此我做了下优化的改良实现. namespace DP { public interface ICreditCard { stri ...

  9. How to: Use XPO Upcasting in XAF 如何:在 XAF 中使用 XPO 强制转换

    In this topic, you will learn how to use the Upcasting feature of XPO in XAF. It is useful when you ...

  10. Redis 实现美团的外卖派单系统“附近的人”筛选实战原理分析

    针对“附近的人”这一位置服务领域的应用场景,常见的可使用PG.MySQL和MongoDB等多种DB的空间索引进行实现.而Redis另辟蹊径,结合其有序队列zset以及geohash编码,实现了空间搜索 ...