2.18从 JSON 发送
框架同样支持从 JSON 配置字符串一键发起 HTTP 请求,完全替代传统的链式调用。只需将请求参数组织为 JSON 格式,传入 HttpRequestBuilder.FromJson() 方,然后通过 IHttpRemoteService 发送即可。
框架同样支持从 JSON 配置字符串一键发起 HTTP 请求,完全替代传统的链式调用。只需将请求参数组织为 JSON 格式,传入 HttpRequestBuilder.FromJson() 方,然后通过 IHttpRemoteService 发送即可。
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://furion.net", "method": "GET" } """));JSON 语法全览#
下表列出了所有可用的 JSON 字段(属性名不区分大小写,且支持尾随逗号):
| 字段 (主键) | 别名 (Aliases) | 类型 | 必填 | 说明 |
|---|---|---|---|---|
method | – | string | 否 | 请求方式(GET、POST、PUT、DELETE、PATCH 等)。若未指定,则根据是否包含请求体自动推断:有请求体时为 POST,否则为 GET。 |
url | requestUri | string | 是 | 请求地址。支持绝对 URI(如 https://api.example.com)或相对路径(如 /api/data)。相对路径可配合 baseURL 使用。 |
baseURL | baseAddress, baseUrl | string | 否 | 请求基地址。必须为绝对 URI。当 url 为相对路径时,两者将按规则拼接为完整地址。 |
headers | – | object | 否 | 请求标头字典。键为标头名称,值为标头值(字符串)。例如 {"Accept": "application/json", "X-API-Key": "xxx"}。 |
params | queries, query, queryParameters | object | 否 | URL 查询参数。将自动拼接到请求地址的 ? 后面。例如 {"page": 1, "size": 10} → ?page=1&size=10。 |
cookies | – | object | 否 | Cookies 字典。例如 {"session": "abc", "user": "john"}。 |
timeout | – | number | 否 | 超时时间(毫秒)。例如 5000 表示 5 秒。 |
client | clientName, httpClientName | string | 否 | IHttpClientFactory 中注册的客户端名称。用于选择特定的 HttpClient 实例。 |
httpVersion | version | string | 否 | HTTP 版本。支持 "1.0"、"1.1"、"2.0"、"3.0" 等。 |
auth | authentication, authorization | object | 否 | 身份认证配置。必须包含 type 字段("bearer"、"basic" 或 "digest")。Bearer 示例: {"type": "bearer", "token": "xxx"},可选 "header" 自定义标头名(默认 Authorization)。Basic 示例: {"type": "basic", "username": "user", "password": "pass"}。Digest 示例: {"type": "digest", "username": "user", "password": "secret"}。 |
data | – | any | 否 | 请求体内容。可以是 JSON 对象、字符串、数字等。框架会将 JsonNode 作为原始内容传递,最终由内容处理器推断 Content-Type。 |
contentType | – | string | 否 | 配合 data 使用,显式指定 Content-Type。若不指定,框架会根据 data 的实际类型自动推断(例如 JSON 对象推断为 application/json)。 |
encoding | – | string | 否 | 配合 data 使用,指定内容编码(如 "utf-8")。若未指定,使用默认编码。 |
multipart | – | object | 否 | 多部分表单(multipart/form-data)内容。对象的每个属性代表一个表单项。普通字段: "name": "John" → 文本字段。文件字段: "file": "@C:\\path\\to\\file.jpg" 或 "@https://example.com/file.png"(网络文件)。支持 @file;type=mime/type 和 @file;filename=renamed.txt 语法。多文件上传: "files": ["@file1.jpg", "@file2.jpg"](数组形式,同一字段名)。 |
profiler | debugger | boolean | 否 | 是否启用请求分析工具。true 启用,false 禁用。 |
注意:当未指定 method 时,框架根据 data 或 multipart 是否存在自动推断:存在则为 POST,否则为 GET。
常规 GET 请求#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://furion.net", "method": "GET" } """));携带查询参数和 JSON 请求体#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/AddModel", "method": "POST", "queries": { "query1": 10, "query2": "hello" }, "headers": { "Content-Type": "application/json" }, "data": { "id": 1, "name": "sample" } } """));多部分表单(文件上传 + 普通字段)#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/AddForm", "method": "POST", "queries": { "id": 100 }, "multipart": { "Id": 100, "Name": "furion", "File": "@C:\\Workspaces\\httptest.jpg" } } """));文件字段值以 @ 开头,支持本地绝对路径或网络 URL(如 "@https://example.com/avatar.png")。同时支持 @path;type=image/png 和 @path;filename=photo.jpg 等扩展语法。
URL 编码表单#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/AddUrlForm", "method": "POST", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "data": "id=200&name=furion" } """));或者通过对象自动序列化(需显式指定 contentType):
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/AddUrlForm", "method": "POST", "data": { "id": 200, "name": "fu rion" }, "contentType": "application/x-www-form-urlencoded" } """));单个文件上传#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/AddFile", "method": "POST", "multipart": { "file": "@C:\\Workspaces\\httptest.jpg" } } """));多个文件上传#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/AddFiles", "method": "POST", "multipart": { "files": ["@C:\\Workspaces\\file1.jpg", "@C:\\Workspaces\\file2.jpg"] } } """));发送原始字符串#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://localhost:7044/HttpRemote/RawString", "method": "POST", "headers": { "Content-Type": "application/json" }, "data": "\"This is a raw string\"" } """));带有认证信息的请求#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://jsonplaceholder.typicode.com/posts", "method": "POST", "headers": { "Content-Type": "application/json" }, "auth": { "type": "basic", "username": "testuser", "password": "testpass" }, "data": { "title": "Test" } } """));指定超时和 HTTP 版本#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://httpbin.org/delay/3", "method": "GET", "timeout": 5000, "httpVersion": "2.0" } """));启用请求分析工具#
var result = await httpRemoteService.SendAsStringAsync( HttpRequestBuilder.FromJson(""" { "url": "https://furion.net", "method": "GET", "profiler": true } """));扩展自定义 JSON 提取器#
与 cURL 解析器类似,JSON 解析也采用可插拔提取器架构。每个 JSON 字段由一个 IHttpJsonExtractor 实现处理。您可以新增自定义提取器来支持私有字段(如 "customField"),而无需修改框架源码。
实现自定义提取器#
最便捷的方式是继承 HttpJsonExtractorBase 抽象基类,它已封装好属性名与别名匹配逻辑:
using HttpAgent;/// <summary>/// 自定义 json.customField 提取器/// </summary>internal sealed class JsonCustomFieldExtractor : HttpJsonExtractorBase{ /// <summary> /// 主属性名 /// </summary> protected override string PropertyName => "customField"; /// <summary> /// 可选别名列表 /// </summary> protected override string[]? Aliases => ["custom", "custom_field"]; /// <summary> /// 当匹配到属性时执行的具体操作 /// </summary> protected override void Extract(HttpRequestBuilder httpRequestBuilder, JsonNode node, HttpJsonParsingContext context) { // 此处根据节点值设置构建器 if (node is JsonValue jsonValue && jsonValue.TryGetValue<string>(out var value)) { httpRequestBuilder.WithHeader("X-Custom-Field", value); } }}对于更复杂的场景,可直接实现 IHttpJsonExtractor 接口,手动遍历根 JsonObject。
注册自定义提取器#
在调用 FromJson 时通过配置委托注入:
var builder = HttpRequestBuilder.FromJson(""" { "url":"http://example.com", "method":"GET", "customField":"hello" } """, options => options.AddExtractor(new JsonCustomFieldExtractor()));如需移除内置提取器,可使用 options.RemoveExtractor<T>()。例如:
var builder = HttpRequestBuilder.FromJson(""" { "url":"http://example.com" } """, options => options.RemoveExtractor<JsonMethodExtractor>());上下文对象说明#
HttpJsonParsingContext 提供了对根 JsonObject 的安全访问方法:
| 成员 | 说明 |
|---|---|
RootObject | 获取根 JsonObject |
TryGetNode(propertyName, out node) | 安全获取指定属性名的 JsonNode,不存在时返回 false |
GetNode(propertyName) | 获取指定属性名的 JsonNode,不存在时返回 null |
ContainsProperty(propertyName) | 检查根对象是否包含指定属性 |
参考实现#
框架内置的所有提取器(如 JsonMethodExtractor、JsonMultipartExtractor 等)均基于相同的基类和接口构建,您可以在仓库中查看其源码作为参考:查看内置 JSON 提取器源码