Files
KinginfoGateway/src/Admin/ThingsGateway.Furion/V5_Experience/HttpRemote/Builders/HttpRequestBuilder.StaticMethods.cs
2025-05-14 18:52:19 +08:00

732 lines
32 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ------------------------------------------------------------------------
// 版权信息
// 版权归百小僧及百签科技(广东)有限公司所有。
// 所有权利保留。
// 官方网站https://baiqian.com
//
// 许可证信息
// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
using System.Reflection;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace ThingsGateway.HttpRemote;
/// <summary>
/// <see cref="HttpRequestMessage" /> 构建器
/// </summary>
public sealed partial class HttpRequestBuilder
{
/// <summary>
/// 创建 <c>GET</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Get(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Get, requestUri, configure);
/// <summary>
/// 创建 <c>GET</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Get(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Get, requestUri, configure);
/// <summary>
/// 创建 <c>PUT</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Put(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Put, requestUri, configure);
/// <summary>
/// 创建 <c>PUT</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Put(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Put, requestUri, configure);
/// <summary>
/// 创建 <c>POST</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Post(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Post, requestUri, configure);
/// <summary>
/// 创建 <c>POST</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Post(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Post, requestUri, configure);
/// <summary>
/// 创建 <c>DELETE</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Delete(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Delete, requestUri, configure);
/// <summary>
/// 创建 <c>DELETE</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Delete(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Delete, requestUri, configure);
/// <summary>
/// 创建 <c>HEAD</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Head(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Head, requestUri, configure);
/// <summary>
/// 创建 <c>HEAD</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Head(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Head, requestUri, configure);
/// <summary>
/// 创建 <c>OPTIONS</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Options(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Options, requestUri, configure);
/// <summary>
/// 创建 <c>OPTIONS</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Options(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Options, requestUri, configure);
/// <summary>
/// 创建 <c>TRACE</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Trace(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Trace, requestUri, configure);
/// <summary>
/// 创建 <c>TRACE</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Trace(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Trace, requestUri, configure);
/// <summary>
/// 创建 <c>PATCH</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Patch(string? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Patch, requestUri, configure);
/// <summary>
/// 创建 <c>PATCH</c> 请求的 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Patch(Uri? requestUri, Action<HttpRequestBuilder>? configure = null) =>
Create(HttpMethod.Patch, requestUri, configure);
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(HttpMethod httpMethod, Uri? requestUri) => new(httpMethod, requestUri);
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(HttpMethod httpMethod, string? requestUri) =>
Create(httpMethod,
string.IsNullOrWhiteSpace(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute));
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(string httpMethod, string? requestUri)
{
// 空检查
ArgumentException.ThrowIfNullOrWhiteSpace(httpMethod);
return Create(Helpers.ParseHttpMethod(httpMethod), requestUri);
}
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(string httpMethod, Uri? requestUri)
{
// 空检查
ArgumentException.ThrowIfNullOrWhiteSpace(httpMethod);
return Create(Helpers.ParseHttpMethod(httpMethod), requestUri);
}
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(HttpMethod httpMethod, Uri? requestUri,
Action<HttpRequestBuilder>? configure)
{
// 初始化 HttpRequestBuilder 实例
var httpRequestBuilder = Create(httpMethod, requestUri);
// 调用自定义配置委托
configure?.Invoke(httpRequestBuilder);
return httpRequestBuilder;
}
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(HttpMethod httpMethod, string? requestUri,
Action<HttpRequestBuilder>? configure) =>
Create(httpMethod,
string.IsNullOrWhiteSpace(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute), configure);
/// <summary>
/// 创建 <see cref="HttpRequestBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
public static HttpRequestBuilder Create(string httpMethod, string? requestUri,
Action<HttpRequestBuilder>? configure)
{
// 空检查
ArgumentException.ThrowIfNullOrWhiteSpace(httpMethod);
return Create(Helpers.ParseHttpMethod(httpMethod), requestUri, configure);
}
/// <summary>
/// 创建 <see cref="HttpFileDownloadBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="destinationPath">文件保存的目标路径</param>
/// <param name="onProgressChanged">用于传输进度发生变化时执行的委托</param>
/// <param name="fileExistsBehavior">
/// <see cref="FileExistsBehavior" />
/// </param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpFileDownloadBuilder" />
/// </returns>
public static HttpFileDownloadBuilder DownloadFile(HttpMethod httpMethod, Uri? requestUri, string? destinationPath,
Func<FileTransferProgress, Task>? onProgressChanged = null,
FileExistsBehavior fileExistsBehavior = FileExistsBehavior.CreateNew,
Action<HttpFileDownloadBuilder>? configure = null)
{
// 初始化 HttpFileDownloadBuilder 实例
var httpFileDownloadBuilder =
new HttpFileDownloadBuilder(httpMethod, requestUri).SetDestinationPath(destinationPath)
.SetFileExistsBehavior(fileExistsBehavior);
// 空检查
if (onProgressChanged is not null)
{
httpFileDownloadBuilder.SetOnProgressChanged(onProgressChanged);
}
// 调用自定义配置委托
configure?.Invoke(httpFileDownloadBuilder);
return httpFileDownloadBuilder;
}
/// <summary>
/// 创建 <see cref="HttpFileDownloadBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="destinationPath">文件保存的目标路径</param>
/// <param name="onProgressChanged">用于传输进度发生变化时执行的委托</param>
/// <param name="fileExistsBehavior">
/// <see cref="FileExistsBehavior" />
/// </param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpFileDownloadBuilder" />
/// </returns>
public static HttpFileDownloadBuilder DownloadFile(Uri? requestUri, string? destinationPath,
Func<FileTransferProgress, Task>? onProgressChanged = null,
FileExistsBehavior fileExistsBehavior = FileExistsBehavior.CreateNew,
Action<HttpFileDownloadBuilder>? configure = null) =>
DownloadFile(HttpMethod.Get, requestUri, destinationPath, onProgressChanged, fileExistsBehavior, configure);
/// <summary>
/// 创建 <see cref="HttpFileDownloadBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="destinationPath">文件保存的目标路径</param>
/// <param name="onProgressChanged">用于传输进度发生变化时执行的委托</param>
/// <param name="fileExistsBehavior">
/// <see cref="FileExistsBehavior" />
/// </param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpFileDownloadBuilder" />
/// </returns>
public static HttpFileDownloadBuilder DownloadFile(string? requestUri, string? destinationPath,
Func<FileTransferProgress, Task>? onProgressChanged = null,
FileExistsBehavior fileExistsBehavior = FileExistsBehavior.CreateNew,
Action<HttpFileDownloadBuilder>? configure = null) =>
DownloadFile(HttpMethod.Get,
string.IsNullOrWhiteSpace(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute),
destinationPath, onProgressChanged, fileExistsBehavior, configure);
/// <summary>
/// 创建 <see cref="HttpFileUploadBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="filePath">文件路径</param>
/// <param name="name">表单名称;默认值为 <c>file</c>。</param>
/// <param name="onProgressChanged">用于传输进度发生变化时执行的委托</param>
/// <param name="fileName">文件的名称</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpFileUploadBuilder" />
/// </returns>
public static HttpFileUploadBuilder UploadFile(HttpMethod httpMethod, Uri? requestUri, string filePath,
string name = "file", Func<FileTransferProgress, Task>? onProgressChanged = null, string? fileName = null,
Action<HttpFileUploadBuilder>? configure = null)
{
// 初始化 HttpFileUploadBuilder 实例
var httpFileUploadBuilder = new HttpFileUploadBuilder(httpMethod, requestUri, filePath, name, fileName);
// 空检查
if (onProgressChanged is not null)
{
httpFileUploadBuilder.SetOnProgressChanged(onProgressChanged);
}
// 调用自定义配置委托
configure?.Invoke(httpFileUploadBuilder);
return httpFileUploadBuilder;
}
/// <summary>
/// 创建 <see cref="HttpFileUploadBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="filePath">文件路径</param>
/// <param name="name">表单名称;默认值为 <c>file</c>。</param>
/// <param name="onProgressChanged">用于传输进度发生变化时执行的委托</param>
/// <param name="fileName">文件的名称</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpFileUploadBuilder" />
/// </returns>
public static HttpFileUploadBuilder UploadFile(Uri? requestUri, string filePath, string name = "file",
Func<FileTransferProgress, Task>? onProgressChanged = null, string? fileName = null,
Action<HttpFileUploadBuilder>? configure = null) =>
UploadFile(HttpMethod.Post, requestUri, filePath, name, onProgressChanged, fileName, configure);
/// <summary>
/// 创建 <see cref="HttpFileUploadBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="filePath">文件路径</param>
/// <param name="name">表单名称;默认值为 <c>file</c>。</param>
/// <param name="onProgressChanged">用于传输进度发生变化时执行的委托</param>
/// <param name="fileName">文件的名称</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpFileUploadBuilder" />
/// </returns>
public static HttpFileUploadBuilder UploadFile(string? requestUri, string filePath, string name = "file",
Func<FileTransferProgress, Task>? onProgressChanged = null, string? fileName = null,
Action<HttpFileUploadBuilder>? configure = null) =>
UploadFile(HttpMethod.Post,
string.IsNullOrWhiteSpace(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute), filePath,
name, onProgressChanged, fileName, configure);
/// <summary>
/// 创建 <see cref="HttpServerSentEventsBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="onMessage">用于在从事件源接收到数据时的操作</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpServerSentEventsBuilder" />
/// </returns>
public static HttpServerSentEventsBuilder ServerSentEvents(HttpMethod httpMethod, Uri? requestUri,
Func<ServerSentEventsData, CancellationToken, Task> onMessage,
Action<HttpServerSentEventsBuilder>? configure = null)
{
// 初始化 HttpServerSentEventsBuilder 实例
var httpServerSentEventsBuilder =
new HttpServerSentEventsBuilder(httpMethod, requestUri).SetOnMessage(onMessage);
// 调用自定义配置委托
configure?.Invoke(httpServerSentEventsBuilder);
return httpServerSentEventsBuilder;
}
/// <summary>
/// 创建 <see cref="HttpServerSentEventsBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="onMessage">用于在从事件源接收到数据时的操作</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpServerSentEventsBuilder" />
/// </returns>
public static HttpServerSentEventsBuilder ServerSentEvents(Uri? requestUri,
Func<ServerSentEventsData, CancellationToken, Task> onMessage,
Action<HttpServerSentEventsBuilder>? configure = null) =>
ServerSentEvents(HttpMethod.Get, requestUri, onMessage, configure);
/// <summary>
/// 创建 <see cref="HttpServerSentEventsBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="onMessage">用于在从事件源接收到数据时的操作</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpServerSentEventsBuilder" />
/// </returns>
public static HttpServerSentEventsBuilder ServerSentEvents(string? requestUri,
Func<ServerSentEventsData, CancellationToken, Task> onMessage,
Action<HttpServerSentEventsBuilder>? configure = null) =>
ServerSentEvents(string.IsNullOrWhiteSpace(requestUri)
? null
: new Uri(requestUri, UriKind.RelativeOrAbsolute), onMessage, configure);
/// <summary>
/// 创建 <see cref="HttpStressTestHarnessBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="numberOfRequests">并发请求数量默认值为100。</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpStressTestHarnessBuilder" />
/// </returns>
public static HttpStressTestHarnessBuilder StressTestHarness(HttpMethod httpMethod, Uri? requestUri,
int numberOfRequests = 100, Action<HttpStressTestHarnessBuilder>? configure = null)
{
// 初始化 HttpStressTestHarnessBuilder 实例
var httpStressTestHarnessBuilder =
new HttpStressTestHarnessBuilder(httpMethod, requestUri).SetNumberOfRequests(numberOfRequests);
// 调用自定义配置委托
configure?.Invoke(httpStressTestHarnessBuilder);
return httpStressTestHarnessBuilder;
}
/// <summary>
/// 创建 <see cref="HttpStressTestHarnessBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="numberOfRequests">并发请求数量默认值为100。</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpStressTestHarnessBuilder" />
/// </returns>
public static HttpStressTestHarnessBuilder StressTestHarness(Uri? requestUri, int numberOfRequests = 100,
Action<HttpStressTestHarnessBuilder>? configure = null) =>
StressTestHarness(HttpMethod.Get, requestUri, numberOfRequests, configure);
/// <summary>
/// 创建 <see cref="HttpStressTestHarnessBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="numberOfRequests">并发请求数量默认值为100。</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpStressTestHarnessBuilder" />
/// </returns>
public static HttpStressTestHarnessBuilder StressTestHarness(string? requestUri, int numberOfRequests = 100,
Action<HttpStressTestHarnessBuilder>? configure = null) =>
StressTestHarness(HttpMethod.Get,
string.IsNullOrWhiteSpace(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute),
numberOfRequests, configure);
/// <summary>
/// 创建 <see cref="HttpLongPollingBuilder" /> 构建器
/// </summary>
/// <param name="httpMethod">请求方式</param>
/// <param name="requestUri">请求地址</param>
/// <param name="onDataReceived">用于接收服务器返回 <c>200~299</c> 状态码的数据的操作</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpLongPollingBuilder" />
/// </returns>
public static HttpLongPollingBuilder LongPolling(HttpMethod httpMethod, Uri? requestUri,
Func<HttpResponseMessage, CancellationToken, Task> onDataReceived,
Action<HttpLongPollingBuilder>? configure = null)
{
// 初始化 HttpLongPollingBuilder 实例
var httpLongPollingBuilder =
new HttpLongPollingBuilder(httpMethod, requestUri).SetOnDataReceived(onDataReceived);
// 调用自定义配置委托
configure?.Invoke(httpLongPollingBuilder);
return httpLongPollingBuilder;
}
/// <summary>
/// 创建 <see cref="HttpLongPollingBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="onDataReceived">用于接收服务器返回 <c>200~299</c> 状态码的数据的操作</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpLongPollingBuilder" />
/// </returns>
public static HttpLongPollingBuilder LongPolling(Uri? requestUri,
Func<HttpResponseMessage, CancellationToken, Task> onDataReceived,
Action<HttpLongPollingBuilder>? configure = null) =>
LongPolling(HttpMethod.Get, requestUri, onDataReceived, configure);
/// <summary>
/// 创建 <see cref="HttpLongPollingBuilder" /> 构建器
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="onDataReceived">用于接收服务器返回 <c>200~299</c> 状态码的数据的操作</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpLongPollingBuilder" />
/// </returns>
public static HttpLongPollingBuilder LongPolling(string? requestUri,
Func<HttpResponseMessage, CancellationToken, Task> onDataReceived,
Action<HttpLongPollingBuilder>? configure = null) =>
LongPolling(HttpMethod.Get,
string.IsNullOrWhiteSpace(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute),
onDataReceived, configure);
/// <summary>
/// 创建 <see cref="HttpDeclarativeBuilder" /> 构建器
/// </summary>
/// <param name="method">被调用方法</param>
/// <param name="args">被调用方法的参数值数组</param>
/// <returns>
/// <see cref="HttpDeclarativeBuilder" />
/// </returns>
public static HttpDeclarativeBuilder Declarative(MethodInfo method, object?[] args) =>
new(method, args);
/// <summary>
/// 从 JSON 中创建 <see cref="HttpRequestBuilder" /> 实例
/// </summary>
/// <param name="json">JSON 字符串</param>
/// <param name="configure">自定义配置委托</param>
/// <returns>
/// <see cref="HttpRequestBuilder" />
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="InvalidOperationException"></exception>
public static HttpRequestBuilder FromJson(string json, Action<HttpRequestBuilder>? configure = null)
{
// 空检查
ArgumentException.ThrowIfNullOrWhiteSpace(json);
/*
* 手动解析 JSON 字符串
*
* 不采用 JSON 反序列化的原因如下:
* 1. HttpRequestBuilder 的属性设计为只读,无法直接通过反序列化赋值。
* 2. 避免引入 [JsonInclude] 特性对 System.Text.Json 的强耦合,保持依赖解耦。
* 3. 简化 JSON 字符串的结构定义,无需严格遵循 HttpRequestBuilder 的属性定义,从而省略 [JsonPropertyName] 等自定义映射。
* 4. 精确控制需要解析的键,减少不必要的自定义 JsonConverter 操作,提升性能与可维护性。
*/
var jsonObject = JsonNode.Parse(json, new JsonNodeOptions { PropertyNameCaseInsensitive = true },
new JsonDocumentOptions { AllowTrailingCommas = true })?.AsObject();
// 空检查
ArgumentNullException.ThrowIfNull(jsonObject);
// 验证必填字段
if (!jsonObject.TryGetPropertyValue("method", out var methodNode) || methodNode is not JsonValue methodValue)
{
throw new ArgumentException("Missing required `method` in JSON.");
}
// 允许 "url" 为 null但必须定义
if (!jsonObject.ContainsKey("url"))
{
throw new ArgumentException("Missing required `url` in JSON.");
}
// 初始化 HttpRequestBuilder 实例
var httpRequestBuilder = Create(methodValue.ToString(), jsonObject["url"]?.GetValue<string?>());
// 处理可选字段
HandleJsonNode(jsonObject, "baseAddress", node => httpRequestBuilder.SetBaseAddress(node.GetValue<string>()));
HandleJsonNode(jsonObject, "headers", node => httpRequestBuilder.WithHeaders(node));
HandleJsonNode(jsonObject, "queries", node => httpRequestBuilder.WithQueryParameters(node));
HandleJsonNode(jsonObject, "cookies", node => httpRequestBuilder.WithCookies(node));
HandleJsonNode(jsonObject, "timeout", node => httpRequestBuilder.SetTimeout(node.GetValue<double>()));
HandleJsonNode(jsonObject, "client", node => httpRequestBuilder.SetHttpClientName(node.GetValue<string?>()));
HandleJsonNode(jsonObject, "profiler", node => httpRequestBuilder.Profiler(node.GetValue<bool>()));
// 处理请求内容
if (jsonObject.TryGetPropertyValue("data", out var dataNode))
{
// "data" 和 "contentType" 必须同时存在或同时不存在
if (!jsonObject.TryGetPropertyValue("contentType", out var contentTypeNode) ||
contentTypeNode is not JsonValue contentTypeValue)
{
throw new InvalidOperationException("The `contentType` key is required when `data` is present.");
}
// 设置请求内容
httpRequestBuilder
.SetContent(
dataNode?.ToJsonString(new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
}), contentTypeValue.ToString()).AddStringContentForFormUrlEncodedContentProcessor();
// 设置内容编码
HandleJsonNode(jsonObject, "encoding",
node => httpRequestBuilder.SetContentEncoding(node.GetValue<string>()));
}
// 处理多部分表单
if (jsonObject.TryGetPropertyValue("multipart", out var multipartNode))
{
// 设置多部分表单内容
httpRequestBuilder.SetMultipartContent(multipart => multipart.AddJson(multipartNode?.AsObject()
.ToJsonString(new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping })));
}
// 调用自定义配置委托
configure?.Invoke(httpRequestBuilder);
return httpRequestBuilder;
}
/// <summary>
/// 处理 <see cref="JsonNode" />
/// </summary>
/// <param name="jsonObject">
/// <see cref="JsonObject" />
/// </param>
/// <param name="propertyName">属性名</param>
/// <param name="action">自定义操作</param>
internal static void HandleJsonNode(JsonObject jsonObject, string propertyName, Action<JsonNode> action)
{
// 空检查
ArgumentNullException.ThrowIfNull(jsonObject);
ArgumentNullException.ThrowIfNull(propertyName);
ArgumentNullException.ThrowIfNull(action);
if (jsonObject.TryGetPropertyValue(propertyName, out var node) && node is not null)
{
action(node);
}
}
}