# 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**: 3 - **Forks**: 3 - **Created**: 2025-11-05 - **Last Updated**: 2026-08-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: net, SCM, Http ## README # Scm.Http English | [中文](README.md) ## Introduction Scm.Http is a lightweight .NET HTTP request utility library built on **.NET Standard 2.0**, compatible with .NET Framework 4.6.1+ and .NET Core 2.0+ / .NET 5+. It provides both synchronous and asynchronous APIs covering **GET, POST, PUT, DELETE** HTTP methods, along with file upload (including chunked upload), file download (with range support), MIME type detection, URL/Base64 encoding utilities, and more — helping developers accomplish common HTTP tasks with minimal code. ## Project Structure ``` Scm.Common.Http/ ├── Config/ │ ├── CertConfig.cs # HTTPS certificate configuration │ └── ProxyConfig.cs # Proxy configuration ├── Utils/ │ ├── HttpUtils.cs # Static HTTP utility methods (core entry) │ └── MimeUtils.cs # MIME type mapping utility ├── HttpConstant.cs # Constants (headers, query symbols, etc.) ├── HttpContentType.cs # Content-Type constants ├── HttpMethod.cs # HTTP method constants (GET/POST/PUT/DELETE) ├── HttpMethodType.cs # HTTP method type (reserved) ├── ScmHttpClient.cs # HTTP client (low-level request engine) ├── ScmHttpParam.cs # Key-value request parameter model ├── ScmHttpRequest.cs # Request wrapper (URL, Header, Body, Query) └── ScmHttpResponse.cs # Response wrapper ``` ## Installation ### Option 1: Reference DLL directly Grab `Scm.Common.Http.dll` from the `Release` directory and add it as a reference in your project. ### Option 2: Source code reference Add the project to your solution and reference it: ```xml ``` > **Note**: This library depends on `Scm.Common.Text.dll` (located in `Libs/`) for JSON serialization/deserialization. ## Core Classes | Class | Description | |-------|-------------| | `ScmHttpClient` | Low-level HTTP client engine with configurable BaseUrl, timeout, UserAgent, cookies, certificates | | `ScmHttpRequest` | Request wrapper managing URL, query parameters, headers, and body content | | `ScmHttpParam` | Key-value request parameter model | | `HttpUtils` | **Core utility class** providing static convenience methods for all HTTP operations | | `MimeUtils` | MIME type utility supporting 100+ file extension ↔ MIME type lookups | | `CertConfig` | HTTPS client certificate configuration | | `ProxyConfig` | HTTP proxy configuration | ## Usage ### GET Requests ```csharp // Sync - returns string string result = HttpUtils.GetString("https://api.example.com/posts/1"); // Sync - returns deserialized object var post = HttpUtils.GetObject("https://api.example.com/posts/1"); // Async - returns string string result = await HttpUtils.GetStringAsync("https://api.example.com/posts", query: new Dictionary { { "userId", "1" } }); // Async - returns deserialized object var post = await HttpUtils.GetObjectAsync("https://api.example.com/posts/1"); // With custom headers var header = new Dictionary { { "Authorization", "Bearer token" } }; string result = await HttpUtils.GetStringAsync("https://api.example.com/data", header: header); ``` ### POST Requests ```csharp // --- Form submission --- var form = new Dictionary { { "username", "admin" }, { "password", "123456" } }; string result = await HttpUtils.PostFormStringAsync("https://api.example.com/login", form); var user = await HttpUtils.PostFormObjectAsync("https://api.example.com/login", form); // --- JSON submission --- string json = "{\"title\":\"hello\",\"body\":\"world\",\"userId\":1}"; string result = await HttpUtils.PostJsonStringAsync("https://api.example.com/posts", json); var post = await HttpUtils.PostJsonObjectAsync("https://api.example.com/posts", json); ``` ### PUT Requests ```csharp // JSON update string json = "{\"id\":1,\"title\":\"updated\",\"body\":\"content\",\"userId\":1}"; string result = await HttpUtils.PutJsonStringAsync("https://api.example.com/posts/1", json); var post = await HttpUtils.PutJsonObjectAsync("https://api.example.com/posts/1", json); // Form update var form = new Dictionary { { "title", "updated" }, { "userId", "1" } }; string result = await HttpUtils.PutFormStringAsync("https://api.example.com/posts/1", form); ``` ### DELETE Requests ```csharp // Basic delete string result = await HttpUtils.DeleteFormStringAsync("https://api.example.com/posts/1"); // Delete with JSON body string result = await HttpUtils.DeleteJsonStringAsync("https://api.example.com/posts/batch", json: "{\"ids\":[1,2,3]}"); ``` ### File Upload ```csharp // Full file upload (sync) string result = HttpUtils.UploadFile( "https://api.example.com/upload", filePath: @"D:\photo.jpg", fileName: "photo.jpg", fieldName: "file", form: new Dictionary { { "tag", "avatar" } } ); // Full file upload (async) string result = await HttpUtils.UploadFileAsync( "https://api.example.com/upload", filePath: @"D:\photo.jpg", fileName: "photo.jpg", fieldName: "file" ); // Upload with progress callback string result = await HttpUtils.UploadFileAsync( "https://api.example.com/upload", filePath: @"D:\large.zip", fileName: "large.zip", callback: (total, transferred) => { int progress = (int)(transferred * 100 / total); Console.WriteLine($"Upload progress: {progress}%"); return 0; } ); // Chunked upload (large files) using (var stream = File.OpenRead(@"D:\video.mp4")) { int chunkSize = 1024 * 1024; var buffer = new byte[chunkSize]; int index = 0, read; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { HttpUtils.UploadFile("https://api.example.com/upload/chunk", buffer, 0, read, $"{index}.chunk", "file", form: new Dictionary { { "index", index.ToString() } }); index++; } } ``` ### File Download ```csharp // Full download bool success = HttpUtils.DownloadFile("https://example.com/file.zip", @"D:\file.zip"); // Download with progress callback success = HttpUtils.DownloadFile( "https://example.com/file.zip", @"D:\file.zip", callback: (total, transferred) => { int progress = (int)(transferred * 100 / total); Console.WriteLine($"Download progress: {progress}%"); return 0; } ); // Range download (resume support) success = HttpUtils.DownloadFile("https://example.com/large.mp4", @"D:\large.mp4", start: 0, end: 1024 * 1024); // Async download success = await HttpUtils.DownloadFileAsync("https://example.com/file.zip", @"D:\file.zip"); // Async download with progress and cancellation var cts = new CancellationTokenSource(); success = await HttpUtils.DownloadFileAsync( "https://example.com/file.zip", @"D:\file.zip", callback: (total, transferred) => { int progress = (int)(transferred * 100 / total); Console.WriteLine($"Download progress: {progress}%"); return 0; }, cancellationToken: cts.Token ); ``` ### MIME Type Utility ```csharp string mime = MimeUtils.GetMimeType("pdf"); // → "application/pdf" string mime = MimeUtils.GetMimeTypeFromFileName("report.xlsx"); // → "...spreadsheetml.sheet" string ext = MimeUtils.GetFileExtension("video/mp4"); // → "mp4" MimeUtils.RegisterCustomMimeType("wasm", "application/wasm"); // Register custom type ``` ### Low-Level Client Usage ```csharp var client = new ScmHttpClient("https://api.example.com") { Timeout = 5000, UserAgent = "MyApp/1.0" }; var request = new ScmHttpRequest("/data"); request.AddQueryParameter("page", "1"); request.AddHeadParameter("Authorization", "Bearer token"); // Sync string text = client.GetText(request); // GET string text = client.PostText(request); // POST string text = client.PutText(request); // PUT string text = client.DeleteText(request); // DELETE // Async string text = await client.GetTextAsync(request); string text = await client.PostTextAsync(request); string text = await client.PutTextAsync(request); string text = await client.DeleteTextAsync(request); ``` ## API Reference | Method | Sync/Async | Description | |--------|------------|-------------| | `GetString` / `GetStringAsync` | Both | GET request, returns string | | `GetObject` / `GetObjectAsync` | Both | GET request, returns deserialized object | | `PostFormString` / `PostFormStringAsync` | Both | POST form data, returns string | | `PostFormObject` / `PostFormObjectAsync` | Both | POST form data, returns deserialized object | | `PostJsonString` / `PostJsonStringAsync` | Both | POST JSON body, returns string | | `PostJsonObject` / `PostJsonObjectAsync` | Both | POST JSON body, returns deserialized object | | `PutJsonString` / `PutJsonStringAsync` | Both | PUT JSON body, returns string | | `PutJsonObject` / `PutJsonObjectAsync` | Both | PUT JSON body, returns deserialized object | | `PutFormString` / `PutFormStringAsync` | Both | PUT form data, returns string | | `PutFormObject` / `PutFormObjectAsync` | Both | PUT form data, returns deserialized object | | `DeleteFormString` / `DeleteFormStringAsync` | Both | DELETE with query params, returns string | | `DeleteFormObject` / `DeleteFormObjectAsync` | Both | DELETE with query params, returns deserialized object | | `DeleteJsonString` / `DeleteJsonStringAsync` | Both | DELETE with JSON body, returns string | | `DeleteJsonObject` / `DeleteJsonObjectAsync` | Both | DELETE with JSON body, returns deserialized object | | `UploadFile` / `UploadFileAsync` | Both | File upload (full / chunked) with progress callback | | `DownloadFile` / `DownloadFileAsync` | Both | File download (full / range) with progress callback and cancellation | ## Tech Stack - **Platform**: .NET Standard 2.0 (compatible with .NET Framework 4.6.1+ / .NET Core 2.0+ / .NET 5+) - **Low-level**: `HttpWebRequest` (unified sync/async), supports GZip/Deflate automatic decompression - **JSON**: Depends on `Scm.Common.Text.dll` (based on Newtonsoft.Json) - **Logging**: Integrated Serilog (Async / Console / File) ## License [MIT License](LICENSE) © 2025 OpenSCM ## Contributing 1. Fork this repository 2. Create a `Feat_xxx` branch 3. Commit your code 4. Create a Pull Request