C# HttpClient 请求认证、数据传输笔记
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 请求消息),比较原生。

对于 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 请求认证、数据传输笔记的更多相关文章
- httpclient请求方法
/** * httpclient请求方法 * @param url 请求地址 * @param paramMap 请求参数 * @param ent 编码格式 gbk.utf-8 * @return ...
- HttpClient请求服务器代码优化版
HttpClient请求服务器代码优化版 首先,我在前面的两篇博文中介绍了在 Android中,除了使用java.net包下HttpUrlConnection的API访问HTTP服务之外,我们还可以换 ...
- 通过HttpClient请求webService
通过HttpClient请求webService 由于服务端是用webService开发的,android要调用webService服务获取数据,这里采用的是通过HttpClient发送post请求, ...
- SpringMVC获取HttpClient 请求的数据
package com.nnk.upstream.controller;import org.springframework.util.StreamUtils;import javax.servlet ...
- .NET 请求认证之access-token(oauth2.0与owin的结合)
公司对外开放的接口,大多需要请求认证,如微信,阿里等.最近我刚好在搭建webapi框架.记录一下自己的理解. 一:请求认证的目的 之所以要对我们的接口进行请求认证,就是为了安全考虑的.以前都是在用 ...
- .NetCore简单封装基于IHttpClientFactory的HttpClient请求
IHttpClientFactory是什么?为什么出现了IHttpClientFactory 一.IHttpClientFactory是什么? IHttpClientFactory是.netcore2 ...
- .NET Core HttpClient请求异常详细情况分析
前言 最近项目上每天间断性捕获到HttpClient请求异常,感觉有点奇怪,于是乎观察了两三天,通过日志以及对接方沟通确认等等,查看对应版本源码,尝试添加部分配置发布后,观察十几小时暂无异常情况出现, ...
- android菜鸟学习笔记24----与服务器端交互(一)使用HttpURLConnection和HttpClient请求服务端数据
主要是基于HTTP协议与服务端进行交互. 涉及到的类和接口有:URL.HttpURLConnection.HttpClient等 URL: 使用一个String类型的url构造一个URL对象,如: U ...
- HttpClient请求详解
HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建 ...
随机推荐
- Python工作好找吗?没有工作经验和学历怎么找?【就业必学】
大家都知道,随着人工智能时代的到来,Python的需求也变的越来越大了.从目前各大IT招聘网上显示招聘需求是非常大,而且薪资基本都在10k起,高的可达40-50k,当然这个要求很高,看下普遍的吧: 一 ...
- Linux配置免密登陆
可能很多新手在配置免密登陆的时候第一次会经常没有配成功,会报错. 在这里将为大家演示最简洁且能一次配置成功的教程 首先以3台机器为例: 192.168.3.102 master 192.168.3.1 ...
- [20191218]降序索引疑问4.txt
[20191218]降序索引疑问4.txt --//前几天优化一个项目,我发现许多表里面有有隐含字段,一般开发很少建立函数索引.我自己检查发现里面存在大量的降序索引.--//我感觉有点奇怪,为什么开发 ...
- centos7搭建ftp服务器并配置匿名用户
什么是FTP? FTP(File Transfer Protocol,文件传输协议),是TCP/IP网络和Internet上最早使用的协议之一.用来将实现从一台电脑传送文件到另一台电脑,或者接收和查看 ...
- 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 ...
- jQuery使用工具集
//jq-util.js$.extend({ Util:{ /* 浏览器 */ browser:{ IE: !!document.all, IE6: !!document.all && ...
- 【译】浅谈SOLID原则
SOLID原则是一种编码的标准,为了避免不良设计,所有的软件开发人员都应该清楚这些原则.SOLID原则是由Robert C Martin推广并被广泛引用于面向对象编程中.正确使用这些规范将提升你的代码 ...
- 工厂模式-C#改良实现
参考了下网上的工厂模式实现,总的来说例子还是OK得,但是示例太单一了,因此我做了下优化的改良实现. namespace DP { public interface ICreditCard { stri ...
- 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 ...
- Redis 实现美团的外卖派单系统“附近的人”筛选实战原理分析
针对“附近的人”这一位置服务领域的应用场景,常见的可使用PG.MySQL和MongoDB等多种DB的空间索引进行实现.而Redis另辟蹊径,结合其有序队列zset以及geohash编码,实现了空间搜索 ...