Ccxc.Core.HttpServer 包
Ccxc.Core.HttpServer 是一个基于 ASP.NET Core Kestrel 的轻量级 HTTP 服务器框架,提供了简化的 Web API 开发体验。该包支持控制器注册、路由匹配、中间件、CORS、参数验证等功能。
命名空间结构
Ccxc.Core.HttpServer
- 核心HTTP服务器类Ccxc.Core.HttpServer.Middlewares
- 中间件功能
核心类
Server 类
HTTP 服务器的核心类,基于 Kestrel 提供 HTTP 服务。
csharp
public class Server
构造函数
csharp
public Server(int port, string prefix = "")
参数:
port
(int
): 监听的端口号prefix
(string
, 可选): 服务提供的路径前缀,如传入 "api" 会在http://ip:port/api
下提供服务
属性
属性名 | 类型 | 描述 |
---|---|---|
Host | IWebHost | 运行中的 WebHost 实例 |
DebugMode | bool | 调试模式开关,控制异常信息的详细程度 |
静态方法
方法名 | 返回类型 | 描述 |
---|---|---|
GetServer(int, string) | Server | 获取 HTTP 服务器实例 |
RegisterController<T>() | void | 注册控制器类 |
RegisterController(object) | void | 注册控制器对象 |
RegisterController(Type) | void | 注册控制器类型 |
RegisterHandler(HttpHandler) | void | 注册 HTTP 处理器 |
RegisterHandler(IEnumerable<HttpHandler>) | void | 批量注册 HTTP 处理器 |
RegisterHandler(string, string, Func<Request, Response, Task>) | void | 注册 HTTP 处理方法 |
AddMiddleware(Func<HttpContext, Func<Task>, Task>) | void | 添加中间件 |
GetInterfaces() | List<string> | 获取所有已注册的接口列表 |
实例方法
方法名 | 返回类型 | 描述 |
---|---|---|
Run() | Task | 启动 HTTP 服务器 |
Stop() | Task | 停止服务器运行 |
Register(HttpHandler) | Server | 注册处理器(链式调用) |
Register(string, string, Func<Request, Response, Task>) | Server | 注册处理方法(链式调用) |
Use(Func<HttpContext, Func<Task>, Task>) | Server | 添加中间件(链式调用) |
HTTP 处理相关类
HttpController 类
HTTP 控制器基类,所有控制器都必须继承此类。
csharp
public class HttpController
{
}
HttpHandlerAttribute 特性
用于标记控制器方法为 HTTP 处理方法的特性。
csharp
public class HttpHandlerAttribute : Attribute
属性
属性名 | 类型 | 描述 |
---|---|---|
Method | string | HTTP 方法,如 GET、POST、PUT 等 |
Path | string | 路径,必须以 "/" 开头 |
构造函数
csharp
public HttpHandlerAttribute(string method, string path)
参数:
method
(string
): HTTP 方法名path
(string
): 匹配的路径
HttpHandler 类
HTTP 处理器类,封装路由和处理逻辑。
csharp
public class HttpHandler
属性
属性名 | 类型 | 描述 |
---|---|---|
Method | string | HTTP 方法 |
Path | string | 路径模式 |
Handler | Func<Request, Response, Task> | 处理方法 |
请求响应类
Request 类
HTTP 请求封装类,提供便捷的请求数据访问。
csharp
public class Request
构造函数
csharp
public Request(HttpRequest request, dynamic pathParam = null)
参数:
request
(HttpRequest
): 原始 HTTP 请求pathParam
(dynamic
, 可选): 路径参数
属性
属性名 | 类型 | 描述 |
---|---|---|
RawRequest | HttpRequest | 原始 ASP.NET Core 请求对象 |
Params | dynamic | 路径参数(如 :id 匹配的值) |
Query | dynamic | 查询字符串参数 |
Header | dynamic | 请求头信息 |
BodyString | string | 请求体字符串 |
Form | dynamic | POST 表单数据 |
ContextItems | IDictionary<object, object> | 上下文项目 |
方法
方法名 | 返回类型 | 描述 |
---|---|---|
Json<T>() | T | 将请求体反序列化为指定类型的对象 |
Response 类
HTTP 响应封装类,提供便捷的响应发送方法。
csharp
public class Response
构造函数
csharp
public Response(HttpResponse response)
参数:
response
(HttpResponse
): 原始 HTTP 响应
属性
属性名 | 类型 | 描述 |
---|---|---|
RawResponse | HttpResponse | 原始 ASP.NET Core 响应对象 |
方法
方法名 | 返回类型 | 描述 |
---|---|---|
SetHeader(string, string) | void | 设置响应头 |
JsonResponse(int, object) | Task | 发送 JSON 响应 |
StringResponse(int, string, string) | Task | 发送字符串响应 |
BinaryResponse(int, byte[], string) | Task | 发送二进制响应 |
静态方法
方法名 | 返回类型 | 描述 |
---|---|---|
SimpleResponse(HttpResponse, int, string, string) | Task | 发送简单响应 |
路由系统
Router 类(内部类)
路由匹配工具类。
csharp
internal class Router
静态方法
方法名 | 返回类型 | 描述 |
---|---|---|
Match(string, string, out dynamic) | bool | 匹配请求路径与处理器路径 |
路径匹配规则:
- 完全匹配:
/api/users
只匹配/api/users
- 参数匹配:
/api/users/:id
匹配/api/users/123
,参数id
值为123
- 支持多个参数:
/api/users/:id/posts/:postId
中间件
Cors 类
CORS(跨域资源共享)中间件。
csharp
public static class Cors
扩展方法
方法名 | 返回类型 | 描述 |
---|---|---|
UseCors(this Server) | Server | 启用 CORS 支持 |
CORS 配置:
- 允许所有源:
Access-Control-Allow-Origin: *
- 允许的方法:
GET
,POST
,PUT
,DELETE
- 允许的头部:
Content-Type
,User-Token
,X-Requested-With
,X-Auth-Token
,Upload-Token
,X-Captcha-Nonce
- 预检缓存时间:600 秒
验证系统
Validation 类
请求参数验证工具类。
csharp
public static class Validation
静态方法
方法名 | 返回类型 | 描述 |
---|---|---|
Valid<T>(T, out string) | bool | 验证模型,返回验证结果和错误信息 |
RequiredAttribute 特性
标记属性为必需的验证特性。
csharp
public class RequiredAttribute : Attribute
属性
属性名 | 类型 | 描述 |
---|---|---|
Message | string | 自定义错误消息 |
异常类
HttpHandlerRegisterException
HTTP 处理器注册异常。
csharp
internal class HttpHandlerRegisterException : Exception
使用示例
基本服务器设置
csharp
// 创建服务器实例
var server = Server.GetServer(8080, "api");
// 启用 CORS
server.UseCors();
// 添加自定义中间件
server.Use(async (context, next) =>
{
// 日志记录
Console.WriteLine($"Request: {context.Request.Method} {context.Request.Path}");
await next();
});
// 启动服务器
await server.Run();
控制器方式
csharp
public class UserController : HttpController
{
[HttpHandler("GET", "/users")]
public async Task GetUsers(Request request, Response response)
{
var users = GetAllUsers(); // 业务逻辑
await response.JsonResponse(200, users);
}
[HttpHandler("GET", "/users/:id")]
public async Task GetUser(Request request, Response response)
{
var userId = request.Params.id;
var user = GetUserById(userId);
if (user == null)
{
await response.JsonResponse(404, new { error = "User not found" });
return;
}
await response.JsonResponse(200, user);
}
[HttpHandler("POST", "/users")]
public async Task CreateUser(Request request, Response response)
{
var userData = request.Json<CreateUserRequest>();
// 参数验证
if (!Validation.Valid(userData, out string reason))
{
await response.JsonResponse(400, new { error = reason });
return;
}
var newUser = CreateUser(userData);
await response.JsonResponse(201, newUser);
}
}
// 注册控制器
Server.RegisterController<UserController>();
直接注册处理器
csharp
// 注册单个处理器
Server.RegisterHandler("GET", "/hello", async (request, response) =>
{
await response.StringResponse(200, "Hello World!");
});
// 链式注册
Server.GetServer(8080)
.Register("GET", "/ping", async (req, res) =>
{
await res.JsonResponse(200, new { message = "pong" });
})
.Register("POST", "/echo", async (req, res) =>
{
var data = req.Json<dynamic>();
await res.JsonResponse(200, data);
})
.UseCors();
请求参数处理
csharp
[HttpHandler("GET", "/search")]
public async Task Search(Request request, Response response)
{
// 查询参数
var keyword = request.Query.keyword;
var page = request.Query.page ?? "1";
// 请求头
var userAgent = request.Header["user-agent"];
var authorization = request.Header.authorization;
var results = SearchService.Search(keyword, int.Parse(page));
await response.JsonResponse(200, results);
}
[HttpHandler("POST", "/upload")]
public async Task Upload(Request request, Response response)
{
// 表单数据
var title = request.Form.title;
var description = request.Form.description;
// 请求体
var body = request.BodyString;
await response.JsonResponse(200, new { success = true });
}
参数验证示例
csharp
public class CreateUserRequest
{
[Required(Message = "用户名不能为空")]
public string Username { get; set; }
[Required(Message = "邮箱地址不能为空")]
public string Email { get; set; }
public string Phone { get; set; } // 可选字段
}
[HttpHandler("POST", "/users")]
public async Task CreateUser(Request request, Response response)
{
var userData = request.Json<CreateUserRequest>();
if (!Validation.Valid(userData, out string reason))
{
await response.JsonResponse(400, new {
success = false,
message = reason
});
return;
}
// 处理有效数据
var user = UserService.Create(userData);
await response.JsonResponse(201, new {
success = true,
data = user
});
}
中间件示例
csharp
// 身份验证中间件
server.Use(async (context, next) =>
{
var path = context.Request.Path.Value;
// 跳过公开路径
if (path.StartsWith("/public"))
{
await next();
return;
}
var token = context.Request.Headers["Authorization"].FirstOrDefault();
if (string.IsNullOrEmpty(token))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Unauthorized");
return;
}
// 验证 token
if (ValidateToken(token))
{
await next();
}
else
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Invalid token");
}
});
// 请求日志中间件
server.Use(async (context, next) =>
{
var stopwatch = Stopwatch.StartNew();
await next();
stopwatch.Stop();
Console.WriteLine($"{context.Request.Method} {context.Request.Path} " +
$"- {context.Response.StatusCode} ({stopwatch.ElapsedMilliseconds}ms)");
});
错误处理
csharp
[HttpHandler("GET", "/users/:id")]
public async Task GetUser(Request request, Response response)
{
try
{
var userId = int.Parse(request.Params.id);
var user = await UserService.GetByIdAsync(userId);
if (user == null)
{
await response.JsonResponse(404, new {
error = "User not found",
code = "USER_NOT_FOUND"
});
return;
}
await response.JsonResponse(200, user);
}
catch (FormatException)
{
await response.JsonResponse(400, new {
error = "Invalid user ID format",
code = "INVALID_FORMAT"
});
}
catch (Exception ex)
{
Logger.Error($"Error in GetUser: {ex}");
await response.JsonResponse(500, new {
error = "Internal server error",
code = "INTERNAL_ERROR"
});
}
}
文件上传处理
csharp
[HttpHandler("POST", "/files/upload")]
public async Task UploadFile(Request request, Response response)
{
if (request.RawRequest.HasFormContentType &&
request.RawRequest.Form.Files.Count > 0)
{
var file = request.RawRequest.Form.Files[0];
var fileName = $"{Guid.NewGuid()}_{file.FileName}";
var filePath = Path.Combine("uploads", fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
await response.JsonResponse(200, new {
success = true,
fileName = fileName,
size = file.Length
});
}
else
{
await response.JsonResponse(400, new {
error = "No file uploaded"
});
}
}
配置选项
调试模式
csharp
var server = Server.GetServer(8080);
server.DebugMode = true; // 显示详细错误信息
自定义错误处理
csharp
server.Use(async (context, next) =>
{
try
{
await next();
}
catch (BusinessException ex)
{
context.Response.StatusCode = 400;
await context.Response.WriteAsync(JsonConvert.SerializeObject(new {
error = ex.Message,
code = ex.Code
}));
}
catch (Exception ex)
{
Logger.Error(ex.ToString());
context.Response.StatusCode = 500;
await context.Response.WriteAsync("Internal server error");
}
});
依赖项
- Microsoft.AspNetCore.Hosting: ASP.NET Core 宿主
- Microsoft.AspNetCore.Server.Kestrel: Kestrel 服务器
- Newtonsoft.Json: JSON 序列化
- Ccxc.Core.Utils: 核心工具包