# Scm.Http **Repository Path**: leadiot/scm.http ## Basic Information - **Project Name**: Scm.Http - **Description**: 基于.Net的网络请求工具类。 - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: http://www.c-scm.net - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 2 - **Created**: 2025-11-05 - **Last Updated**: 2026-06-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: net, SCM, Http ## README # Scm.Http ## 介绍 Scm.Http 是一个轻量级 .NET HTTP 请求工具库,基于 **.NET Standard 2.0** 构建,兼容 .NET Framework 4.6.1+ 及 .NET Core 2.0+ / .NET 5+。 库内提供了同步与异步两套 API,覆盖 **GET、POST、PUT、DELETE** 四种 HTTP 方法,并封装了文件上传(含分片)、文件下载(含断点续传)、MIME 类型识别、URL/Base64 编码等实用功能,帮助开发者以最少的代码完成常见的 HTTP 通信需求。 ## 项目结构 ``` Scm.Common.Http/ ├── Config/ │ ├── CertConfig.cs # HTTPS 证书配置 │ └── ProxyConfig.cs # 代理配置 ├── Utils/ │ ├── HttpUtils.cs # HTTP 静态工具方法(核心入口) │ └── MimeUtils.cs # MIME 类型映射工具 ├── HttpConstant.cs # 常量定义(Header、Query 符号等) ├── HttpContentType.cs # Content-Type 常量 ├── HttpMethod.cs # HTTP 方法常量(GET/POST/PUT/DELETE) ├── HttpMethodType.cs # HTTP 方法类型(备用) ├── ScmHttpClient.cs # HTTP 客户端(底层请求引擎) ├── ScmHttpParam.cs # 请求参数键值对模型 ├── ScmHttpRequest.cs # 请求封装(URL、Header、Body、Query) └── ScmHttpResponse.cs # 响应封装 ``` ## 安装 ### 方式一:直接引用 DLL 从 `Release` 目录获取 `Scm.Common.Http.dll`,在项目中添加引用即可。 ### 方式二:源码引用 将本项目作为子模块或直接复制到解决方案中,通过项目引用添加: ```xml ``` > **注意**:本项目依赖 `Scm.Common.Text.dll`(位于 `Libs/` 目录),用于 JSON 序列化/反序列化。 ## 核心类说明 | 类名 | 说明 | |------|------| | `ScmHttpClient` | 底层 HTTP 客户端引擎,支持配置 BaseUrl、超时、UserAgent、Cookie、证书等 | | `ScmHttpRequest` | 请求封装对象,管理 URL、Query 参数、Header、Body 等内容 | | `ScmHttpParam` | 请求参数键值对模型 | | `HttpUtils` | **核心工具类**,提供静态便捷方法,覆盖全部 HTTP 操作 | | `MimeUtils` | MIME 类型工具,支持 100+ 种文件后缀与 MIME 类型互查 | | `CertConfig` | HTTPS 客户端证书配置 | | `ProxyConfig` | HTTP 代理配置 | ## 使用说明 ### 一、GET 请求 ```csharp // 同步 - 返回字符串 string result = HttpUtils.GetString("https://api.example.com/posts/1"); // 同步 - 返回反序列化对象 var post = HttpUtils.GetObject("https://api.example.com/posts/1"); // 异步 - 返回字符串 string result = await HttpUtils.GetStringAsync("https://api.example.com/posts", query: new Dictionary { { "userId", "1" } }); // 异步 - 返回反序列化对象 var post = await HttpUtils.GetObjectAsync("https://api.example.com/posts/1"); // 携带自定义请求头 var header = new Dictionary { { "Authorization", "Bearer token" } }; string result = await HttpUtils.GetStringAsync("https://api.example.com/data", header: header); ``` ### 二、POST 请求 ```csharp // --- 表单提交 --- var form = new Dictionary { { "username", "admin" }, { "password", "123456" } }; // 同步 string result = HttpUtils.PostFormString("https://api.example.com/login", form); var user = HttpUtils.PostFormObject("https://api.example.com/login", form); // 异步 string result = await HttpUtils.PostFormStringAsync("https://api.example.com/login", form); var user = await HttpUtils.PostFormObjectAsync("https://api.example.com/login", form); // --- JSON 提交 --- string json = "{\"title\":\"hello\",\"body\":\"world\",\"userId\":1}"; // 同步 string result = HttpUtils.PostJsonString("https://api.example.com/posts", json); var post = HttpUtils.PostJsonObject("https://api.example.com/posts", json); // 异步 string result = await HttpUtils.PostJsonStringAsync("https://api.example.com/posts", json); var post = await HttpUtils.PostJsonObjectAsync("https://api.example.com/posts", json); ``` ### 三、PUT 请求 ```csharp // --- JSON 更新 --- string json = "{\"id\":1,\"title\":\"updated\",\"body\":\"content\",\"userId\":1}"; // 同步 string result = HttpUtils.PutJsonString("https://api.example.com/posts/1", json); var post = HttpUtils.PutJsonObject("https://api.example.com/posts/1", json); // 异步 string result = await HttpUtils.PutJsonStringAsync("https://api.example.com/posts/1", json); var post = await HttpUtils.PutJsonObjectAsync("https://api.example.com/posts/1", json); // --- 表单更新 --- var form = new Dictionary { { "title", "updated" }, { "userId", "1" } }; // 同步 string result = HttpUtils.PutFormString("https://api.example.com/posts/1", form); // 异步 string result = await HttpUtils.PutFormStringAsync("https://api.example.com/posts/1", form); var post = await HttpUtils.PutFormObjectAsync("https://api.example.com/posts/1", form); ``` ### 四、DELETE 请求 ```csharp // 同步 - 基本删除 string result = HttpUtils.DeleteFormString("https://api.example.com/posts/1"); // 异步 - 基本删除 string result = await HttpUtils.DeleteFormStringAsync("https://api.example.com/posts/1"); // 同步 - 携带 JSON 请求体删除 string result = HttpUtils.DeleteJsonString("https://api.example.com/posts/batch", json: "{\"ids\":[1,2,3]}"); // 异步 - 携带 JSON 请求体删除并反序列化 var resp = await HttpUtils.DeleteJsonObjectAsync( "https://api.example.com/posts/batch", json: "{\"ids\":[1,2,3]}"); ``` ### 五、文件上传 ```csharp // 整文件上传 string result = HttpUtils.UploadFile( "https://api.example.com/upload", filePath: @"D:\photo.jpg", fileName: "photo.jpg", fieldName: "file", form: new Dictionary { { "tag", "avatar" } } ); // 分片上传(大文件) using (var stream = File.OpenRead(@"D:\video.mp4")) { int chunkSize = 1024 * 1024; // 1MB var buffer = new byte[chunkSize]; int index = 0; int read; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { var result = HttpUtils.UploadFile( "https://api.example.com/upload/chunk", buffer, 0, read, fileName: $"{index}.chunk", fieldName: "file", form: new Dictionary { { "index", index.ToString() } } ); index++; } } ``` ### 六、文件下载 ```csharp // 完整下载 HttpUtils.DownloadFile("https://example.com/file.zip", @"D:\file.zip"); // 断点续传(分片下载) HttpUtils.DownloadFile("https://example.com/large.mp4", @"D:\part1.mp4", start: 0, end: 1024 * 1024); // 异步下载 await HttpUtils.DownloadFileAsync("https://example.com/file.zip", @"D:\file.zip"); ``` ### 七、底层客户端直接使用 ```csharp var client = new ScmHttpClient("https://api.example.com") { Timeout = 5000, // 超时 5 秒 UserAgent = "MyApp/1.0", AllowAutoRedirect = true }; var request = new ScmHttpRequest("/data"); request.AddQueryParameter("page", "1"); request.AddHeadParameter("Authorization", "Bearer token"); // GET string text = client.GetText(request); byte[] bytes = client.GetByte(request); // POST request.ContentType = HttpContentType.APPLICATION_JSON; request.AddBodyContent("{\"key\":\"value\"}"); string text = client.PostText(request); // PUT request.ContentType = HttpContentType.APPLICATION_JSON; request.AddBodyContent("{\"key\":\"updated\"}"); string text = client.PutText(request); // DELETE string text = client.DeleteText(request); // 异步版本 string text = await client.GetTextAsync(request); string text = await client.PostTextAsync(request); string text = await client.PutTextAsync(request); string text = await client.DeleteTextAsync(request); ``` ### 八、MIME 类型工具 ```csharp // 根据后缀获取 string mime = MimeUtils.GetMimeType("pdf"); // → "application/pdf" string mime = MimeUtils.GetMimeType(".jpg"); // → "image/jpeg" // 根据文件名获取 string mime = MimeUtils.GetMimeTypeFromFileName("report.xlsx"); // → "...spreadsheetml.sheet" // 反向查找后缀 string ext = MimeUtils.GetFileExtension("video/mp4"); // → "mp4" // 注册自定义类型 MimeUtils.RegisterCustomMimeType("wasm", "application/wasm"); ``` ### 九、公共工具方法 ```csharp // URL 编码 string encoded = HttpUtils.UrlEncode("你好世界"); // Query 字符串构建 var query = new Dictionary { { "a", "1" }, { "b", "2" } }; string url = HttpUtils.BuildQuery(query, "https://api.com/list"); // → "https://api.com/list?a=1&b=2" // Query 解析 var dict = HttpUtils.Query2Dictionary("a=1&b=2&c=3"); // → { "a":"1", "b":"2", "c":"3" } // Base64 URL 安全编码 string safe = HttpUtils.ToBase64String(bytes); // 用 -_ 替代 +/ byte[] raw = HttpUtils.FromBase64String(safe); // 还原 // Escape / Unescape string escaped = HttpUtils.Escape("hello world!"); string unescaped = HttpUtils.Unescape(escaped); // 网络信息 string ip = HttpUtils.GetIp(); // 获取本机 IPv4 bool isV4 = HttpUtils.IsIPv4("192.168.1.1"); // 判断 IPv4 格式 // HTML / XML 转义 string html = HttpUtils.Db2Html("