You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HttpClientStudy/Docs/1.3.1.基础使用.发送请求.ipynb

351 lines
12 KiB
Plaintext

11 months ago
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
11 months ago
"# 基础使用-发送请求"
11 months ago
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
8 months ago
"## 0、初始化与全局设置"
]
},
{
"cell_type": "code",
8 months ago
"execution_count": null,
8 months ago
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
8 months ago
"outputs": [],
8 months ago
"source": [
"//全局设置,行运行一次,为后续准备\n",
"#r \"nuget:System.Net.Http.Json\"\n",
"#r \"nuget:Microsoft.Net.Http.Headers\"\n",
"#r \"nuget:Microsoft.Extensions.Http\"\n",
"#r \"nuget:Microsoft.Extensions.DependencyInjection\"\n",
8 months ago
"#r \"./Publish/HttpClientStudy.Model/HttpClientStudy.Model.dll\"\n",
8 months ago
"#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n",
"\n",
"global using System;\n",
"global using System.Collections;\n",
"global using System.Collections.Concurrent;\n",
"global using System.Linq;\n",
"global using System.Linq.Expressions;\n",
"global using System.Threading;\n",
"global using System.Threading.Tasks;\n",
"global using System.Net.Http;\n",
"//System.Net.Http.Json 包含处理json的扩展方法方便处理请求和影响中的json数据\n",
"global using System.Net.Http.Json;\n",
"global using Microsoft.Extensions.DependencyInjection;\n",
"global using Microsoft.Extensions.DependencyInjection.Extensions;\n",
"\n",
"global using HttpClientStudy.Config;\n",
"global using HttpClientStudy.Core;\n",
"global using HttpClientStudy.Core.Utilities;\n",
"\n",
"//全局变量\n",
"var webApiBaseUrl = WebApiConfigManager.GetWebApiConfig().BaseUrl;\n",
"var workDir = Environment.CurrentDirectory;\n",
"var fullPath = System.IO.Path.GetFullPath(\"./Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.exe\", workDir);\n",
"\n",
"//全局共享静态 HttpClient 对象\n",
"public static HttpClient SharedClient = new HttpClient(new SocketsHttpHandler(){ PooledConnectionIdleTimeout = TimeSpan.FromSeconds(30)})\n",
"{\n",
" BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl),\n",
"};\n",
"\n",
"//启动已发布的WebApi项目\n",
"{\n",
" Console.WriteLine(\"启动WebApi项目\");\n",
" var startMessage = AppUtility.RunWebApiExeFile(fullPath);\n",
" Console.WriteLine(startMessage);\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1、创建HttpClient"
11 months ago
]
11 months ago
},
{
"cell_type": "markdown",
"metadata": {},
8 months ago
"source": [
"根据 系列教程的 `管理客户端` 一章, 创建的HttpClient对象有非常多的方式。\n",
"为方便演示,本节使用两种:一种是全局共享对象(SharedClient, 在初始化时创建), 符合共享的使用原则; 一种是临时实例化对象。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2、发出 Http请求"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Http 简介"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"http是无状态的请求/响应模式。\n",
"\n",
"客户端请求: 请求行(方法 URL 协议版本 回车换行符)、请求头、空行及可选的请求体;\n",
"\n",
"![客户端请求消息](./Assets/RequestMessage.png)\n",
"\n",
"服务器响应:状态行(协议版本 状态码 状态码描述 回车换行符)、响应头及可选的响应体。\n",
"\n",
"![客户端请求消息](./Assets/ResponseMessage.jpg)\n"
8 months ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"### Http 请求方法"
8 months ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Http请求方法可通过多种特性区分\n",
"\n",
"1. 谓词也就是请求方法Post、Get、Put、Delete、Options、Head等\n",
"2. 幂等性:如果可多次成功处理某个请求方法而不改变结果,则该请求方法是幂等的;\n",
"3. 可缓存性:如果可以存储请求方法的相应响应以供重复使用,则该请求方法是可缓存的;\n",
"4. 安全性:如果请求方法不会修改资源的状态,则被视为安全方法。所有安全方法也都是幂等方法,但并非所有幂等方法都是安全方法;\n",
"\n",
" | **HTTP 方法** | **是否是幂等的** | **是否可缓存** | **是否安全** |\n",
" | ------------- | ---------------- | -------------- | ------------ |\n",
" | `GET` | ✔️ 是 | ✔️ 是 | ✔️ 是 |\n",
" | `POST` | ❌ 否 | ⚠️ †很少 | ❌ 否 |\n",
" | `PUT` | ✔️ 是 | ❌ 否 | ❌ 否 |\n",
" | `PATCH` | ❌ 否 | ❌ 否 | ❌ 否 |\n",
" | `DELETE` | ✔️ 是 | ❌ 否 | ❌ 否 |\n",
" | `HEAD` | ✔️ 是 | ✔️ 是 | ✔️ 是 |\n",
" | `OPTIONS` | ✔️ 是 | ❌ 否 | ✔️ 是 |\n",
" | `TRACE` | ✔️ 是 | ❌ 否 | ✔️ 是 |\n",
" | `CONNECT` | ❌ 否 | ❌ 否 | ❌ 否 |\n",
"> \n",
">†仅当存在相应的 Cache-Control 或 Expires 响应标头时POST 方法才可缓存。 这在实践中非常罕见。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Http 状态码"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Http 状态码是响应的首要标识,指定响应的不同结果,分为以下几类:\n",
"\n",
"1. 1xx信息表示临时响应大多数临时响应 (例如 HttpStatusCode.Continue) 使用 HttpClient 在内部处理,并且永远不会显示给用户;\n",
"2. 2xx成功表示请求已被成功接收、理解、并接受\n",
"3. 3xx重定向表示需要完成一个或多个附加步骤才能完成请求自动重定向默认处于打开状态可以使用 HttpClientHandler.AllowAutoRedirect 或 SocketsHttpHandler.AllowAutoRedirect 进行更改;\n",
"4. 4xx客户端错误表示客户端的请求无效(请求包含语法错误或无法完成请求)\n",
"5. 5xx服务器错误表示服务器在处理请求的过程中发生了错误。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"### 使用 HttpClient 发出请求"
8 months ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"要发出 HTTP 请求,请调用以下任一 API\n",
"\n",
"| HTTP 方法 | API |\n",
"| ----------------- | ---------------------------- |\n",
"| `GET` | HttpClient.GetAsync |\n",
"| `GET` | HttpClient.GetByteArrayAsync |\n",
"| `GET` | HttpClient.GetStreamAsync |\n",
"| `GET` | HttpClient.GetStringAsync |\n",
"| `POST` | HttpClient.PostAsync |\n",
"| `PUT` | HttpClient.PutAsync |\n",
"| `PATCH` | HttpClient.PatchAsync |\n",
"| `DELETE` | HttpClient.DeleteAsync |\n",
"| †`USER SPECIFIED` | HttpClient.SendAsync |\n",
"\n",
"<br>\n",
"\n",
"> †USER SPECIFIED 请求指示 SendAsync 方法接受任何有效的 HttpMethod。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Http 内容"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"HttpContent 类型用于表示 HTTP 实体正文和相应的内容标头。 对于需要正文的 HTTP 方法或请求方法POST、PUT 和 PATCH可使用 HttpContent 类来指定请求的正文。\n",
"大多数示例演示如何使用 JSON 有效负载准备 StringContent 子类,但还有针对其他内容 (MIME) 类型的其他子类。\n",
"\n",
"- ByteArrayContent提供基于字节数组的 HTTP 内容;\n",
"- FormUrlEncodedContent为使用 \"application/x-www-form-urlencoded\" MIME 类型编码的名称/值元组提供 HTTP 内容;\n",
"- JsonContent提供基于 JSON 的 HTTP 内容;\n",
"- MultipartContent提供使用 \"multipart/*\" MIME 类型规范进行序列化的 HttpContent 对象的集合;\n",
"- MultipartFormDataContent为使用 \"multipart/form-data\" MIME 类型进行编码的内容提供容器;\n",
"- ReadOnlyMemoryContent提供基于 ReadOnlyMemory<T> 的 HTTP 内容;\n",
"- StreamContent提供基于流的 HTTP 内容;\n",
"- StringContent提供基于字符串的 HTTP 内容\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"### Http Get"
8 months ago
]
8 months ago
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"GET 请求不应发送正文,而是用于从资源检索数据。 要在给定 HttpClient 和 URI 的情况下发出 HTTP GET 请求,推荐使用 HttpClient.GetAsync 方法。\n",
"\n",
"> Get 请求,一般不会发送数据(服务器支持的话,也能带),最大特点是:可以缓存请求结果,减少服务器压力。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"//Get 请求\n",
"{\n",
" //使用共享客户端发送Get请求\n",
" var response = await SharedClient.GetAsync(\"/api/hello/index\");\n",
"\n",
" //确保请求成功\n",
" response.EnsureSuccessStatusCode();\n",
"\n",
" //读取响应内容\n",
" var content = await response.Content.ReadAsStringAsync();\n",
"\n",
" //输出 响应内容\n",
" Console.WriteLine(content);\n",
"}"
8 months ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"## Http Get Json"
8 months ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
8 months ago
"System.Net.Http.Json 库为请求Json格式数据和接受json格式数据提供了很多扩展方法使用 HttpClient 发送和请求Json格式数据非常方便; \n",
"后面单独章节讲解,这里只是一个例子."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"/*\n",
" Get Json\n",
" 需要先引入 System.Net.Http.Json 和 命名空间(全局设置里已完成)\n",
"*/\n",
"{\n",
"\n",
" //使用共享客户端发送Get请求\n",
" var content = await SharedClient.GetFromJsonAsync<HttpClientStudy.Model.Account>(\"/api/hello/GetAccount\");\n",
"\n",
" //框架显示方法\n",
" content.Display();\n",
"}"
8 months ago
]
11 months ago
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "python"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}