# 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