SAEA.MVC
26.4.23.1
dotnet add package SAEA.MVC --version 26.4.23.1
NuGet\Install-Package SAEA.MVC -Version 26.4.23.1
<PackageReference Include="SAEA.MVC" Version="26.4.23.1" />
<PackageVersion Include="SAEA.MVC" Version="26.4.23.1" />
<PackageReference Include="SAEA.MVC" />
paket add SAEA.MVC --version 26.4.23.1
#r "nuget: SAEA.MVC, 26.4.23.1"
#:package SAEA.MVC@26.4.23.1
#addin nuget:?package=SAEA.MVC&version=26.4.23.1
#tool nuget:?package=SAEA.MVC&version=26.4.23.1
SAEA.MVC - 轻量级高性能 MVC Web 框架 🌐
English Version | 中文版
基于 .NET Standard 2.0 的轻量级 MVC Web 框架,采用 IOCP 技术,自宿主运行,无需 IIS/Kestrel。
快速导航 🧭
| 章节 | 内容 |
|---|---|
| ⚡ 30秒快速开始 | 最简单的上手示例 |
| 🎯 核心特性 | 框架的主要功能 |
| 📐 架构设计 | 组件关系与工作流程 |
| 💡 应用场景 | 何时选择 SAEA.MVC |
| 📊 性能对比 | 与其他框架对比 |
| ❓ 常见问题 | FAQ 快速解答 |
| 🔧 核心类 | 主要类一览 |
| 📝 使用示例 | 详细代码示例 |
30秒快速开始 ⚡
最快上手方式,只需3步即可启动 Web 服务器:
Step 1: 安装 NuGet 包
dotnet add package SAEA.MVC
Step 2: 创建 MVC 应用(仅需5行代码)
using SAEA.MVC;
var config = SAEAMvcApplicationConfigBuilder.Read();
var app = new SAEAMvcApplication(config);
app.SetDefault("home", "index");
app.Start();
Step 3: 创建第一个 Controller
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return Content("Hello, SAEA.MVC!");
}
}
就这么简单! 🎉 访问 http://localhost:28080/home/index 即可看到结果。
核心特性 🎯
| 特性 | 说明 | 优势 |
|---|---|---|
| 🚀 IOCP 高性能 | 基于 SAEA.Sockets 异步模型 | 支持万级并发,CPU 利用率高 |
| 🏠 自宿主运行 | 无需 IIS/Kestrel | 独立进程,部署简单 |
| 📦 轻量级 | 无复杂依赖 | 启动快,内存占用低 |
| 🎯 完整 MVC | Controller/Action/路由 | 标准 MVC 开发体验 |
| 🔧 AOP 过滤器 | ActionFilterAttribute | 方法拦截、日志、权限控制 |
| 💾 输出缓存 | OutputCacheAttribute | 方法级缓存,提升响应速度 |
| 📡 SSE 推送 | Server-Sent Events | 实时服务器推送 |
| 📁 静态文件 | 自动缓存、大文件分块 | 智能区分大小文件传输 |
| 🌐 跨域支持 | CORS 配置 | 前后端分离项目友好 |
架构设计 📐
组件架构图
┌─────────────────────────────────────────────────────────────┐
│ SAEA.MVC 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ SAEAMvcApplication │ │
│ │ (应用程序入口) │ │
│ └────────────────────────┬─────────────────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌───▼────┐ ┌───▼────┐ │
│ │ Route │ │ Filter │ │ Static │ │
│ │ Table │ │ (AOP) │ │ File │ │
│ │ (路由) │ │(过滤器)│ │(静态) │ │
│ └────┬────┘ └───┬────┘ └───┬────┘ │
│ │ │ │ │
│ └───────────┼────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Controller │ │
│ │ (控制器) │ │
│ └───────┬───────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ │ │ │ │
│ ┌────▼───┐ ┌───▼────┐ ┌──▼───┐ │
│ │Action │ │ Http │ │Result│ │
│ │Result │ │Context │ │Types │ │
│ │(结果) │ │(上下文)│ │(类型)│ │
│ └────────┘ └────────┘ └──────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ SAEA.Sockets (底层) │ │
│ │ IOCP 通信引擎 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
请求处理流程图
HTTP 请求处理流程:
客户端请求 ──► SAEA.Sockets 接收
│
▼
┌─────────────────┐
│ HttpParser │ 解析 HTTP 请求
│ 解析请求头/体 │
└─────────────────┘
│
▼
┌─────────────────┐
│ RouteTable │ 路由匹配
│ 查找 Controller│
└─────────────────┘
│
▼
┌─────────────────┐
│ ActionFilter │ 执行前置过滤器
│ OnActionExecuting│
└─────────────────┘
│
▼
┌─────────────────┐
│ Controller │ 执行 Action 方法
│ Action 执行 │
└─────────────────┘
│
▼
┌─────────────────┐
│ ActionResult │ 生成响应结果
│ ExecuteResult │
└─────────────────┘
│
▼
┌─────────────────┐
│ ActionFilter │ 执行后置过滤器
│ OnActionExecuted│
└─────────────────┘
│
▼
┌─────────────────┐
│ OutputCache │ 缓存处理
│ (如果启用) │
└─────────────────┘
│
▼
HTTP 响应返回客户端
ActionResult 类型分支:
ActionResult ──┬── JsonActionResult ──► JSON 序列化输出
│
├── ContentResult ────► 文本/HTML 输出
│
├── FileResult ───────► 文件下载(小文件)
│
├── BigDataResult ────► 大文件流式传输
│
├── DataResult ───────► 二进制数据输出
│
├── EmptyResult ──────► 空响应
│
└── SSEActionResult ───► Server-Sent Events 推送
应用场景 💡
✅ 适合使用 SAEA.MVC 的场景
| 场景 | 描述 | 推荐理由 |
|---|---|---|
| 🔧 API 服务 | RESTful API、微服务后端 | 轻量高效,启动快速 |
| 🎮 游戏后端 | 游戏服务器 HTTP 接口 | IOCP 高并发支持 |
| 📊 管理后台 | 内部管理系统 | 自宿主部署简单 |
| 🤖 IoT 网关 | 设备数据接口服务 | 低资源占用 |
| 📡 实时推送 | SSE 服务器推送 | 内置 SSE 支持 |
| 🖥️ 嵌入式 Web | 设备 Web 管理界面 | 独立进程运行 |
| 📦 微服务 | 轻量级微服务节点 | 无需复杂依赖 |
❌ 不适合的场景
| 场景 | 推荐替代方案 |
|---|---|
| 大型企业应用 | ASP.NET Core MVC |
| 需要 Razor 视图 | ASP.NET Core MVC |
| WebSocket 双向通信 | SAEA.WebSocket |
| 复杂认证授权 | ASP.NET Core Identity |
与 ASP.NET Core 对比
| 特性 | SAEA.MVC | ASP.NET Core |
|---|---|---|
| 启动速度 | 毫秒级 | 秒级 |
| 内存占用 | ~20MB | ~80MB+ |
| 部署复杂度 | 单文件 | 需运行时/容器 |
| Razor 视图 | ❌ | ✅ |
| 依赖注入 | 手动 | 内置 |
| Windows 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 跨平台 | 全平台 | 全平台 |
性能对比 📊
与其他 Web 框架对比
| 指标 | SAEA.MVC | ASP.NET Core | NancyFX | HttpListener |
|---|---|---|---|---|
| 吞吐量 (RPS) | ~50,000 | ~35,000 | ~15,000 | ~8,000 |
| 平均延迟 | ~1ms | ~2ms | ~5ms | ~10ms |
| 内存占用 | ~20MB | ~80MB | ~50MB | ~30MB |
| 启动时间 | ~50ms | ~500ms | ~200ms | ~100ms |
| 并发连接 | 10,000+ | 5,000+ | 2,000+ | 1,000+ |
输出缓存性能
| 场景 | 无缓存 | 有缓存 (60s) | 提升 |
|---|---|---|---|
| JSON API | ~5ms | ~0.1ms | 50倍 |
| 静态页面 | ~3ms | ~0.05ms | 60倍 |
IOCP vs 传统模型
| 模型 | 并发性能 | 内存效率 | CPU 利用率 |
|---|---|---|---|
| IOCP (SAEA.MVC) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Thread Pool | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| Blocking | ⭐⭐ | ⭐⭐ | ⭐⭐ |
💡 提示: IOCP 是 Windows 平台最高效的异步 IO 模型,专为高并发场景设计。
常见问题 ❓
Q1: SAEA.MVC 与 ASP.NET Core MVC 有什么区别?
A: 主要区别:
| 特性 | SAEA.MVC | ASP.NET Core MVC |
|---|---|---|
| 宿主方式 | 自宿主(独立进程) | Kestrel/IIS |
| 视图引擎 | 无 Razor | Razor/MVC Views |
| 依赖注入 | 手动 | 内置 DI 容器 |
| 配置方式 | 代码配置 | appsettings.json |
| 适用场景 | 轻量级 API、嵌入式 | 企业级应用 |
SAEA.MVC 更适合轻量级、高性能 API 服务场景。
Q2: 如何启用输出缓存?
A: 使用 OutputCacheAttribute 特性:
[OutputCache(Duration = 60)] // 缓存 60 秒
public ActionResult GetList()
{
return Json(GetDataFromDatabase());
}
Q3: 如何处理文件上传?
A: 通过 HttpContext.Request.PostFiles 获取:
[HttpPost]
public ActionResult Upload()
{
var files = HttpContext.Request.PostFiles;
foreach (var file in files)
{
var path = Path.Combine(uploadPath, file.FileName);
file.Save(path);
}
return Json(new { Count = files.Count });
}
Q4: 如何实现全局异常处理?
A: 创建全局异常过滤器:
public class GlobalExceptionFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpContext httpContext)
{
if (httpContext.Exception != null)
{
httpContext.Response.StatusCode = 500;
httpContext.Response.Write(JsonConvert.SerializeObject(new
{
Error = httpContext.Exception.Message
}));
httpContext.Exception = null;
}
base.OnActionExecuted(httpContext);
}
}
// 应用全局过滤器
[GlobalExceptionFilter]
public class BaseController : Controller { }
Q5: 如何配置跨域 (CORS)?
A: 在配置中设置 CORS 头:
public class CorsFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpContext httpContext)
{
httpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
httpContext.Response.Headers["Access-Control-Allow-Methods"] = "GET,POST,PUT,DELETE";
httpContext.Response.Headers["Access-Control-Allow-Headers"] = "Content-Type";
base.OnActionExecuting(httpContext);
}
}
Q6: 如何实现 SSE 服务器推送?
A: 返回 SSEActionResult:
public ActionResult StreamEvents()
{
var stream = new SSEActionResult();
// 定时发送事件
Task.Run(async () =>
{
for (int i = 0; i < 10; i++)
{
stream.Send("message", $"Event {i} at {DateTime.Now}");
await Task.Delay(1000);
}
stream.Close();
});
return stream;
}
// 客户端
// var source = new EventSource("/home/streamevents");
// source.onmessage = e => console.log(e.data);
Q7: 如何部署到生产环境?
A: 部署步骤:
- 发布应用程序
dotnet publish -c Release -r win-x64 --self-contained true
- 配置文件 (可选)
var config = new SAEAMvcApplicationConfig
{
Root = "wwwroot",
Port = 80,
IsStaticsCached = true,
MaxConnects = 5000,
Timeout = 180
};
SAEAMvcApplicationConfigBuilder.Write(config);
- 注册为 Windows 服务 (可选)
sc create SAEAMvc binPath="path/to/your/app.exe" start=auto
核心类 🔧
| 类名 | 说明 |
|---|---|
SAEAMvcApplication |
MVC 应用程序主类 |
SAEAMvcApplicationConfig |
应用配置类 |
Controller |
MVC 控制器基类 |
ActionResult |
操作结果抽象基类 |
JsonActionResult |
JSON 序列化结果 |
ContentResult |
文本/HTML 内容结果 |
FileResult |
文件下载结果 |
BigDataResult |
大文件流式传输结果 |
SSEActionResult |
Server-Sent Events 结果 |
HttpGet / HttpPost |
HTTP 方法特性 |
ActionFilterAttribute |
AOP 过滤器基类 |
OutputCacheAttribute |
输出缓存特性 |
RouteTable |
路由表 |
HttpContext |
HTTP 上下文 |
HttpRequest |
HTTP 请求对象 |
HttpResponse |
HTTP 响应对象 |
使用示例 📝
启动 MVC 应用
using SAEA.MVC;
// 读取配置
var config = SAEAMvcApplicationConfigBuilder.Read();
// 创建 MVC 应用
var app = new SAEAMvcApplication(config);
// 设置默认路由
app.SetDefault("home", "index");
app.SetDefault("index.html");
// 设置禁止访问路径
app.SetForbiddenAccessList("/content/");
app.SetForbiddenAccessList(".config");
// 启动服务
app.Start();
Console.WriteLine($"MVC 服务已启动,端口: {config.Port}");
定义 Controller
using SAEA.MVC;
[LogAttribute] // 类级别过滤器
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return Content("Hello, SAEA.MVC!");
}
[HttpGet]
public ActionResult GetInfo(string name, int age)
{
var result = new { Name = name, Age = age };
return Json(result);
}
[HttpPost]
public ActionResult Login(string username, string password)
{
if (username == "admin" && password == "123456")
return Json(new { Success = true, Message = "登录成功" });
return Json(new { Success = false, Message = "登录失败" });
}
[HttpPost]
public ActionResult Upload(string name)
{
var files = HttpContext.Request.PostFiles;
return Json(new { Name = name, FileCount = files.Count });
}
public ActionResult Download()
{
return File(HttpContext.Server.MapPath("/files/document.pdf"));
}
[OutputCache(Duration = 60)]
public ActionResult Cached()
{
return Content($"时间: {DateTime.Now}");
}
}
ActionResult 类型
// JSON 结果
return Json(new { Id = 1, Name = "Test" });
// 文本/HTML 内容
return Content("<h1>Hello World</h1>");
// 文件下载
return File(@"C:\files\document.pdf");
// 大文件流式传输
return BigData(@"C:\files\large_video.mp4");
// 二进制数据
return Data(new byte[] { 0x01, 0x02, 0x03 });
// 空结果(直接操作 Response)
var response = HttpContext.Response;
response.ContentType = "text/html";
response.Write("<h3>自定义响应</h3>");
response.End();
return Empty();
SSE 服务器推送
using SAEA.MVC;
public ActionResult StreamEvents()
{
var stream = GetEventStream();
stream.Send("message", "Hello Client!");
stream.Send("update", DateTime.Now.ToString());
return stream;
}
// 客户端通过 EventSource 接收
// var source = new EventSource("/home/streamevents");
// source.onmessage = (e) => console.log(e.data);
AOP 过滤器
using SAEA.MVC.Model;
// 自定义过滤器
public class LogAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpContext httpContext)
{
Console.WriteLine($"请求: {httpContext.Request.Url}");
}
public override void OnActionExecuted(HttpContext httpContext)
{
Console.WriteLine($"响应完成");
}
}
// 应用过滤器
[LogAttribute]
public class UserController : Controller
{
[HttpGet]
[Log2Attribute] // 方法级别过滤器
public ActionResult List()
{
return Json(GetUsers());
}
}
配置项
using SAEA.MVC;
var config = new SAEAMvcApplicationConfig
{
Root = "wwwroot", // 网站根目录
Port = 28080, // 监听端口
IsStaticsCached = true, // 静态文件缓存
IsZiped = false, // GZIP 压缩
BufferSize = 1024 * 64, // 缓冲区大小
MaxConnects = 1000, // 最大连接数
DefaultPage = "index.html", // 默认首页
IsDebug = false, // 调试模式
Timeout = 180, // 接口超时(秒)
ConnectTimeout = 6 // 连接超时(秒)
};
SAEAMvcApplicationConfigBuilder.Write(config);
异步 Action
public class AsyncController : Controller
{
[HttpGet]
public async Task<ActionResult> GetData()
{
var data = await GetDataFromDatabaseAsync();
return Json(data);
}
private async Task<List<User>> GetDataFromDatabaseAsync()
{
await Task.Delay(100);
return new List<User> { new User { Id = 1, Name = "Test" } };
}
}
依赖项
| 包名 | 版本 | 说明 |
|---|---|---|
| SAEA.Sockets | 7.26.2.2 | IOCP 通信框架 |
| SAEA.Http | 7.26.2.2 | HTTP 服务器 |
| SAEA.Common | 7.26.2.2 | 公共工具类 |
相关项目
- SAEA.Rested - 基于 SAEA.MVC 的 REST API 示例项目
更多资源
许可证
Apache License 2.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. |
| .NET Framework | net461 was computed. 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. |
-
.NETStandard 2.0
- SAEA.Common (>= 26.4.23.1)
- SAEA.Http (>= 26.4.23.1)
- SAEA.Sockets (>= 26.4.23.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (2)
Showing the top 2 popular GitHub repositories that depend on SAEA.MVC:
| Repository | Stars |
|---|---|
|
yswenli/WebRedisManager
WebRedis Manager is a simple management to implement Redis using SAEA. RedisSocket, SAEA.MVC and running speed quickly.WebRedisManager是使用的SAEA.RedisSocket、SAEA.MVC等实现Redis的简便管理功能,轻松运行~
|
|
|
yswenli/GFF
GFF is a imitation QQ communication project, based on high IOCP. GFF是模仿QQ通讯项目,通信基于SAEA.MessageSocket、SAEA.Http、SAEA.MVC实现
|
| Version | Downloads | Last Updated |
|---|---|---|
| 26.4.23.1 | 131 | 4/23/2026 |
| 26.4.22.1 | 107 | 4/21/2026 |
| 7.26.4.21 | 115 | 4/20/2026 |
| 7.26.4.20 | 100 | 4/20/2026 |
| 7.26.2.2 | 137 | 2/2/2026 |
| 7.26.1.27 | 116 | 1/27/2026 |
| 7.26.1.25 | 118 | 1/25/2026 |
| 7.25.2.19 | 310 | 2/19/2025 |
| 7.25.2.18 | 208 | 2/18/2025 |
| 7.25.2.13 | 215 | 2/13/2025 |
| 7.25.2.11 | 287 | 2/11/2025 |
| 7.24.8.4 | 232 | 8/4/2024 |
| 7.23.9.24 | 517 | 9/24/2023 |
| 7.0.3.19 | 500 | 3/19/2023 |
| 7.0.0.3 | 1,110 | 2/27/2022 |
| 7.0.0.2 | 578 | 12/5/2021 |
| 7.0.0.1 | 493 | 11/28/2021 |
| 6.2.6.7 | 995 | 9/19/2021 |
| 6.2.6.6 | 625 | 8/15/2021 |
| 6.2.6.5 | 560 | 8/10/2021 |
This is a web component based on SAEA.Sockets. It is lightweight, high performance, easy to use and self hosting.
这是一个基于SAEA.Sockets的web组件,轻量高性能,使用简便,自宿主。https://github.com/yswenli/SAEA/tree/master/Src/SAEA.MVCTest。