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

287 lines
10 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
"# 基础使用-发送请求"
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
"## 0、初始化与全局设置"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>Microsoft.Extensions.DependencyInjection, 8.0.0</span></li><li><span>Microsoft.Extensions.Http, 8.0.0</span></li><li><span>Microsoft.Net.Http.Headers, 8.0.8</span></li><li><span>System.Net.Http.Json, 8.0.0</span></li></ul></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"配置文件根目录e:\\王高峰\\我的项目\\学习项目\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.Core\n",
"启动WebApi项目\n",
"程序[e:\\王高峰\\我的项目\\学习项目\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.exe]已在新的命令行窗口执行。如果未出现新命令行窗口,可能是程序错误造成窗口闪现!\n"
]
}
],
"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",
"#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"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"根据 系列教程的 `管理客户端` 一章, 创建的HttpClient对象有非常多的方式。\n",
"为方便演示,本节使用两种:一种是全局共享对象(SharedClient, 在初始化时创建), 符合共享的使用原则; 一种是临时实例化对象。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2、发出 Http请求"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Http 简介"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"http是无状态的请求/响应模式。请求包括:请求行(方法 URL 协议版本 回车换行符)、请求头及可选的请求体;响应包括:状态行(协议版本 状态码 状态码描述 回车换行符)、响应头及可选的响应体。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Http请求方法"
]
},
{
"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": [
"### 发出 http 请求"
]
},
{
"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": [
"## 3、处理 http 响应"
]
}
],
"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
}