X.Helper.Http 1.0.2.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package X.Helper.Http --version 1.0.2.3
                    
NuGet\Install-Package X.Helper.Http -Version 1.0.2.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="X.Helper.Http" Version="1.0.2.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="X.Helper.Http" Version="1.0.2.3" />
                    
Directory.Packages.props
<PackageReference Include="X.Helper.Http" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add X.Helper.Http --version 1.0.2.3
                    
#r "nuget: X.Helper.Http, 1.0.2.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package X.Helper.Http@1.0.2.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=X.Helper.Http&version=1.0.2.3
                    
Install as a Cake Addin
#tool nuget:?package=X.Helper.Http&version=1.0.2.3
                    
Install as a Cake Tool

X.Helper.Http

X.Helper.Http 是基于 HttpClient 的轻量封装,面向常见业务 HTTP 场景,提供链式配置与可编程请求体两种用法。

支持能力:

  • 常规请求:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/TRACE
  • 请求体:RAW / x-www-form-urlencoded / multipart/form-data / binary
  • 文件上传(含进度、取消)
  • 文件下载(流式落盘)
  • SSE 流式接收
  • Header / Cookie / 超时 / 编码 / 重试 / HTTP 版本配置

目标框架

  • >= net4.6.1
  • netstandard2.0
  • netstandard2.1
  • >= net6.0

说明:SSE 在 .NET Framework 目标下已弃用,建议在 net6.0+ 使用。


核心类型

Client

请求入口与链式配置核心类型。

常用能力:

  • 基础配置:SetUriSetMethodSetTimeoutSetEncodingSetHttpVersion
  • 调试:SetDebugEnabledSetDebugLogger
  • Header:SetHeaderSetDefaultRequestHeadersSetRefererSetOriginSetUserAgent
  • Cookie:SetCookieClearCookies
  • 请求体:SetContentType + AddContent / AddFile
  • 请求发送:RequestByteAsyncRequestTextContentRequestDownloadFile
  • 上传:RequestUploadFileAsync(...)(支持 IProgress<double> + CancellationToken
  • SSE:RequestSSEWithCallbackAsync(...).NET 6+ 额外支持 RequestSSEAsyncEnumerable(...)
    • returnRawEventBlock = true(默认):回调/枚举返回完整事件块原文(含自定义字段)
    • returnRawEventBlock = false:仅返回 data: 字段(兼容历史行为)

Result

统一响应结果:

  • 状态:StatusCodeStatusDescriptionIsSuccess
  • 头与 Cookie:HeaderCollectionCookieCollection
  • 内容:Content(文本)、Bytes(字节)
  • 其他:ResponseUriRedirectUrlContentTypeDownloadFilePath

HttpHandler

HttpClientHandler 的配置封装:

  • 代理、自动重定向、自动解压
  • CookieContainer
  • 证书验证回调、客户端证书
  • 凭据配置

Helper.HttpContentCreator

可编程请求体构建器,适合复杂 body 场景;与 RequestByteAsync(contentCreator)RequestTextContent(contentCreator) 配合使用。


两种请求体模式(重要)

Client 支持两种 body 配置方式:

  1. 链式:SetContentType(...) + AddContent(...) / AddFile(...)
  2. 参数:RequestTextAsync(contentCreator)RequestByteAsync(contentCreator)

同一次请求中,这两种方式不可同时使用。若同时配置会抛出异常。

另外:

  • contentCreator 模式下当前不支持自动重试(SetRetryCount > 0 会抛异常)。
  • 链式 MULTIPART_FORM_DATA 已支持同时提交表单字段 + AddFile(...) 文件。

SetContentType(...) 行为说明

  • SetContentType(...)Set 语义是“重置并切换类型”。
  • 调用后会清空此前通过 AddContent(...) 添加的内容参数,这是预期行为,不是缺陷。
  • 推荐调用顺序:先 SetContentType(...),再 AddContent(...) / AddFile(...)
  • 如果先 AddContent(...)SetContentType(...),之前内容会被清空。
// 推荐:先 SetContentType,再 AddContent
var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.X_WWW_FORM_URLENCODED)
    .AddContent("name", "alice")
    .RequestTextContent();

快速开始

1) GET + 文本响应

using var client = new X.Helper.Http.Client("https://httpbin.org/get");

var result = await client
    .SetMethod(X.Helper.Http.Enums.HttpMethod.GET)
    .RequestTextContent();

if (result.IsSuccess)
    Console.WriteLine(result.Content);

2) POST JSON(链式 body)

using var client = new X.Helper.Http.Client("https://httpbin.org/post");

var result = await client
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent("{\"name\":\"SystemX\",\"age\":18}")
    .RequestTextContent();

3) POST 表单(HttpContentCreator

var creator = new X.Helper.Http.Helper.HttpContentCreator(
    X.Helper.Http.Enums.HttpContentType.X_WWW_FORM_URLENCODED);

creator.AddContent("name", "SystemX")
       .AddContent("role", "admin");

using var client = new X.Helper.Http.Client("https://httpbin.org/post");

var result = await client
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .RequestTextContent(creator);

4) multipart(链式表单 + 文件)

using var client = new X.Helper.Http.Client("https://example.com/upload");

var result = await client
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.MULTIPART_FORM_DATA)
    .AddContent("bizType", "avatar")
    .AddFile("file", @"D:\data\avatar.png")
    .RequestTextAsync();

5) 文件上传(进度 + 取消)

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var progress = new Progress<double>(p => Console.WriteLine($"上传进度: {p:P1}"));

using var client = new X.Helper.Http.Client("https://example.com/upload");

var result = await client
    .AddFile("file", @"D:\data\test.bin")
    .RequestUploadFileAsync(progress, cts.Token);

6) 文件下载(流式)

using var client = new X.Helper.Http.Client("https://example.com/file.zip");

var result = await client
    .SetAutoCreateDirectory(true)
    .RequestDownloadFile(@"D:\download\file.zip");

Console.WriteLine(result.DownloadFilePath);

7) SSE 流式接收(net6.0+ 推荐)

using var client = new X.Helper.Http.Client("https://example.com/sse");

await client.RequestSSEWithCallbackAsync(
    onChunk: async chunk =>
    {
        Console.WriteLine($"SSE: {chunk}");
        await Task.CompletedTask;
    },
    returnRawEventBlock: true);

returnRawEventBlock 默认值为 true,会返回完整事件块(包括 data/event/id/retry、注释和自定义标识行)。 如果仅需要传统 data: 内容,请设置 returnRawEventBlock: false

.NET 6+ 可使用异步枚举:

await foreach (var chunk in client.RequestSSEAsyncEnumerable(returnRawEventBlock: true))
{
    Console.WriteLine(chunk);
}

标准链式调用模板(建议直接复用)

模板 A:普通 GET

var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.GET)
    .RequestTextContent(token);

模板 B:JSON 提交(POST/PUT/PATCH)

var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent(json)
    .RequestTextContent(token);

模板 C:表单提交(x-www-form-urlencoded

var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.X_WWW_FORM_URLENCODED)
    .AddContent("name", "alice")
    .AddContent("age", 18)
    .RequestTextContent(token);

模板 D:multipart(表单 + 文件,走 RequestTextAsync

var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.MULTIPART_FORM_DATA)
    .AddContent("bizType", "avatar")
    .AddFile("file", @"D:\\data\\avatar.png")
    .RequestTextAsync(cancellationToken: token);

模板 E:专用上传(带进度)

var progress = new Progress<double>(p => Console.WriteLine($"upload: {p:P1}"));

var result = await new X.Helper.Http.Client(url)
    .AddFile("file", @"D:\\data\\big.bin")
    .RequestUploadFileAsync(progress, token);

模板 F:流式下载到文件

var result = await new X.Helper.Http.Client(url)
    .SetAutoCreateDirectory(true)
    .RequestDownloadFile(@"D:\\download\\target.zip", token);

模板 G:SSE(net6.0+

await new X.Helper.Http.Client(url).RequestSSEWithCallbackAsync(
    onChunk: chunk =>
    {
        Console.WriteLine(chunk);
        return Task.CompletedTask;
    },
    cancellationToken: token,
    returnRawEventBlock: true);

顺序规则:基础配置 → Header/Cookie → SetContentTypeAddContent/AddFile → 发送。

冲突规则:

  • SetContentType(...) 会清空已添加请求体参数。
  • 链式 body 与 contentCreator 参数不可同时使用。
  • contentCreator 模式下不支持自动重试(SetRetryCount > 0 会抛异常)。

常见错误示例(反例)

反例 1:先 AddContentSetContentType

// ? 错误:SetContentType 会清空之前 AddContent 的参数
var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .AddContent("name", "alice")
    .SetContentType(X.Helper.Http.Enums.HttpContentType.X_WWW_FORM_URLENCODED)
    .RequestTextContent();
// ? 正确:先 SetContentType,再 AddContent
var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.X_WWW_FORM_URLENCODED)
    .AddContent("name", "alice")
    .RequestTextContent();

反例 2:链式 body 与 contentCreator 同时使用

// ? 错误:同一次请求不能同时使用两套请求体配置
var creator = new X.Helper.Http.Helper.HttpContentCreator(
    X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent("{\"name\":\"alice\"}");

var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent("{\"name\":\"bob\"}")
    .RequestTextAsync(creator); // 将抛 InvalidOperationException

反例 3:contentCreator 模式下启用自动重试

// ? 错误:contentCreator 模式不支持 RetryCount > 0
var creator = new X.Helper.Http.Helper.HttpContentCreator(
    X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent("{\"name\":\"alice\"}");

var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetRetryCount(2)
    .RequestTextAsync(creator); // 将抛 InvalidOperationException

反例 4:默认 GET 却试图发送 body

// ? 错误:未设置方法时默认 GET,GET 场景不会发送请求体
var result = await new X.Helper.Http.Client(url)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent("{\"name\":\"alice\"}")
    .RequestTextAsync();
// ? 正确:显式设置 POST/PUT/PATCH 等支持请求体的方法
var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.RAW_JSON)
    .AddContent("{\"name\":\"alice\"}")
    .RequestTextAsync();

反例 5:AddFile 后未使用 multipart 或专用上传接口

// ? 易错:AddFile 后若未设置 MULTIPART_FORM_DATA,文件不会按预期进入普通请求体
var result = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .AddFile("file", @"D:\\data\\a.bin")
    .RequestTextAsync();
// ? 方式 A:普通请求中显式设置 multipart
var resultA = await new X.Helper.Http.Client(url)
    .SetMethod(X.Helper.Http.Enums.HttpMethod.POST)
    .SetContentType(X.Helper.Http.Enums.HttpContentType.MULTIPART_FORM_DATA)
    .AddFile("file", @"D:\\data\\a.bin")
    .RequestTextAsync();

// ? 方式 B:直接使用专用上传接口
var resultB = await new X.Helper.Http.Client(url)
    .AddFile("file", @"D:\\data\\a.bin")
    .RequestUploadFileAsync();

常用配置与行为说明

请求体顺序

推荐顺序:

  1. SetContentType(...)
  2. AddContent(...) / AddFile(...)

SetContentType(...) 会清空当前已添加的请求体参数。

  • SetDefaultRequestHeaders:作用于当前 Client 实例生命周期内的所有请求
  • SetHeader:作用于单次请求消息

调试输出

  • 默认关闭,通过 SetDebugEnabled(true) 开启。
  • 可通过 SetDebugLogger(Action<string>) 自定义输出位置(如 ILogger、文件、控制台)。
  • 开启后会输出关键节点信息:
    • 请求参数(含 Header/Cookie 完整值、请求体参数、文件参数)
    • 请求过程(发送、重试、超时、异常、完成)
    • 响应信息(状态码、响应头、Cookie、响应正文/字节长度)
    • SSE 每个返回块的完整内容
using var client = new X.Helper.Http.Client(url)
    .SetDebugEnabled(true)
    .SetDebugLogger(msg => Console.WriteLine(msg));

重试

  • 通过 SetRetryCount(int) 配置
  • RequestTextAsyncRequestByteAsync 参与重试
  • 上传/下载/SSE 不参与重试
  • 非成功状态码仅对以下状态自动重试:4084295xx

支持两种模式:

  1. 手动 SetCookie(...)
  2. HttpHandler.CookieContainer

建议不要混用;混用时以实际请求写入为准。

HTTP 版本

  • 默认 HTTP/1.1
  • 可通过 SetHttpVersion(...) 指定版本

结果与异常建议

  • 业务判断优先使用 result.IsSuccess
  • 失败优先查看 result.StatusDescription
  • 文本响应读取 result.Content
  • 字节响应读取 result.Bytes
  • 上传/下载/SSE 建议始终传入 CancellationToken

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.3 70 8/11/2026
1.0.2.4 109 6/17/2026
1.0.2.3 118 6/16/2026
1.0.2.2 111 6/11/2026
1.0.2.1 108 6/7/2026