Acme.ReturnOh
1.7.5
dotnet add package Acme.ReturnOh --version 1.7.5
NuGet\Install-Package Acme.ReturnOh -Version 1.7.5
<PackageReference Include="Acme.ReturnOh" Version="1.7.5" />
<PackageVersion Include="Acme.ReturnOh" Version="1.7.5" />
<PackageReference Include="Acme.ReturnOh" />
paket add Acme.ReturnOh --version 1.7.5
#r "nuget: Acme.ReturnOh, 1.7.5"
#:package Acme.ReturnOh@1.7.5
#addin nuget:?package=Acme.ReturnOh&version=1.7.5
#tool nuget:?package=Acme.ReturnOh&version=1.7.5
Acme.ReturnOh 使用文档
项目简介
Acme.ReturnOh 是一个用于 .NET 项目的通用返回参数处理库,提供了统一的 API 响应格式、全局异常处理、参数验证和 Swagger 配置功能。
当前版本 1.7.5
更新内容
- 添加JWT 认证未通过拦截,返回统一错误信息
- 修复已知bug……
主要功能
- 统一的 API 响应格式
- 全局异常处理
- 参数验证错误处理
- Swagger 文档配置(支持多版本、JWT 认证)
- 自定义异常过滤器支持
安装方法
通过 NuGet 安装
dotnet add package Acme.ReturnOh
支持的框架版本
- .NET 8.0
- .NET 9.0
- .NET 10.0
快速开始
1. 配置服务
在 Program.cs 文件中添加以下配置:
using Acme.ReturnOh;
var builder = WebApplication.CreateBuilder(args);
// 配置 Swagger(默认启用 JWT 认证和方法排序)
builder.Services.ConfigureSwaggerOptions("API 文档");
// 配置 API 行为选项(参数验证)
builder.Services.ConfigureApiBehaviorOptions();
// 配置异常过滤器
builder.Services.AddExceptionFilterService();
// 添加 MVC
builder.Services.AddControllers();
//添加认证服务(1.7.5 -beta版本新增)
builder.Services.AddOhAuthentication();
var app = builder.Build();
// 启用 Swagger(单版本)
app.UseSingSwagger("API 文档");
app.UseAuthorization();
app.MapControllers();
app.Run();
在 csproj 文件中添加以下配置:
<Project Sdk="Microsoft.NET.Sdk.Web">
<Target Name="CopyNuGetXmlToOutput" AfterTargets="Build">
<ItemGroup>
<NuGetXmlFile Include="@(ReferenceCopyLocalPaths->WithMetadataValue('NuGetPackageId','Acme.ReturnOh'))" />
</ItemGroup>
<Copy SourceFiles="%(NuGetXmlFile.RootDir)%(NuGetXmlFile.Directory)%(NuGetXmlFile.Filename).xml"
DestinationFolder="$(OutputPath)"
SkipUnchangedFiles="true"
Condition="Exists('%(NuGetXmlFile.RootDir)%(NuGetXmlFile.Directory)%(NuGetXmlFile.Filename).xml')" />
</Target>
<PropertyGroup>
2. 使用通用返回格式
在控制器中使用 Oh 类返回统一格式的响应:
using Acme.ReturnOh;
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet(Name = "GetWeatherForecast")]
public Oh Get()
{
var forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray();
return forecasts.Success("获取成功");
}
}
核心功能
1. 通用返回格式
基本结构
public record Oh(int Code, string Msg, object? Data = null);
public record Oh<TEntity>(int Code, string Msg, TEntity? Data) where TEntity : class, new();
常用方法
// 成功响应
return data.Success(); // 默认消息:"成功!"
return data.Success("操作成功"); // 自定义消息
return data.Success(200, "操作成功"); // 自定义状态码和消息
// 失败响应
return data.Fail(); // 默认消息:"服务器错误!请联系管理员"
return data.Fail("操作失败"); // 自定义消息
return data.Fail(500, "操作失败"); // 自定义状态码和消息
// 自定义响应
return data.Custom(403, "权限不足"); // 自定义状态码和消息
// 布尔值转换
return isSuccess.IsSuccess("成功消息", "失败消息");
// 静态方法(data 为 null 时)
return Oh.Success("操作成功");
return Oh.Fail("操作失败");
// 泛型版本
return data.Success<UserDto>("获取成功");
return data.Fail<UserDto>("操作失败");
return data.Custom<UserDto>(403, "权限不足");
2. 异常处理
全局异常过滤器
库会自动捕获并处理以下异常:
ArgumentException- 返回 400 状态码SystemException- 返回 500 状态码- 其他异常 - 返回 500 状态码
手动抛出异常
// 抛出普通异常
Oh.Exception("操作失败");
// 抛出自定义异常
Oh.ArgumentException("参数错误");
Oh.SystemException("系统错误");
3. 参数验证
自动处理
当使用 [ApiController] 特性时,参数验证错误会自动处理并返回统一格式的错误响应:
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
[HttpPost]
public Oh Create([FromBody] UserDto user)
{
// 如果 user 参数验证失败,会自动返回 400 状态码和错误消息
return user.Success("创建成功");
}
}
public class UserDto
{
[Required(ErrorMessage = "用户名不能为空")]
public string Username { get; set; }
[Required(ErrorMessage = "密码不能为空")]
[MinLength(6, ErrorMessage = "密码长度不能少于6位")]
public string Password { get; set; }
}
4. Swagger 配置
基本配置(单版本)
// 配置 Swagger
builder.Services.ConfigureSwaggerOptions("API 文档");
// 启用 Swagger
app.UseSingSwagger("API 文档");
高级配置(单版本)
// 配置 Swagger(自定义参数)
builder.Services.ConfigureSwaggerOptions(
title: "API 文档",
version: "v1",
otherFiles: null, // 其他 XML 注释文件
isActionOrder: true, // 是否启用方法排序
enableJwtBearerAuth: true // 是否启用 JWT 认证
);
// 启用 Swagger(自定义路由前缀)
app.UseSingSwagger(
title: "API 文档",
version: "v1",
routePrefix: "swagger" // 访问路径:/swagger
);
多版本配置
// 配置多版本 Swagger
var swaggerDocs = new List<SwaggerDocDto>
{
new("后台管理 API", "v1"),
new("移动端 API", "v2"),
new("第三方 API", "v3")
};
builder.Services.ConfigureSwaggerOptions(swaggerDocs);
// 启用多版本 Swagger
app.UseBathSwagger(swaggerDocs, "swagger");
包含其他 XML 注释文件
// 包含其他项目的 XML 注释文件
var otherXmlFiles = new List<string>
{
"MyProject.Model",
"MyProject.Service"
};
builder.Services.ConfigureSwaggerOptions("API 文档", "v1", otherXmlFiles);
JWT 认证配置
Swagger 默认启用 JWT 认证,认证方案 ID 为 CV.SecuritySchemeId(值为 "Bearer")。
在 Swagger UI 中,点击右上角的 "Authorize" 按钮,输入格式为 Bearer {token} 的 JWT token 即可。
高级用法
1. 自定义异常过滤器
public class CustomExceptionFilter : Attribute, IAsyncExceptionFilter
{
public async Task OnExceptionAsync(ExceptionContext context)
{
if (context.ExceptionHandled)
return;
Oh result = context.Exception switch
{
MyCustomException ex =>
new Oh(400, $"自定义异常:{ex.Message}"),
_ =>
Oh.Fail($"系统错误:{context.Exception.Message}"),
};
context.ExceptionHandled = true;
context.Result = new ObjectResult(result);
await Task.CompletedTask;
}
}
// 注册自定义异常过滤器
builder.Services.AddExceptionFilterService<CustomExceptionFilter>();
2. 泛型返回类型
[HttpGet("{id}")]
public Oh<UserDto> Get(int id)
{
var user = _userService.GetById(id);
if (user == null)
{
return new Oh<UserDto>(404, "用户不存在", null);
}
return user.Success<UserDto>("获取成功");
}
3. 使用 NewOh 静态方法
// 使用静态方法创建 Oh 实例
var result = Oh<UserDto>.NewOh(200, "操作成功", userDto);
常量定义
库中定义了一些常用常量,可直接使用:
| 常量名 | 值 | 说明 |
|---|---|---|
CV.BlankCharacter |
"" | 空字符串 |
CV.LoginUserKey |
"LoginUserKey" | 当前登录人员键 |
CV.VerCodeKey |
"ImgVerCode" | 验证码键 |
CV.Yes |
"成功!" | 成功消息 |
CV.ErrorPrompt |
"系统错误!请联系管理员" | 系统错误提示 |
CV.ErrorServer |
"服务器错误!请联系管理员" | 服务器错误提示 |
CV.YesCode |
200 | 成功状态码 |
CV.NoCode |
500 | 失败状态码 |
CV.InsertYes |
"新增成功" | 新增成功消息 |
CV.InsertNo |
"新增失败" | 新增失败消息 |
CV.UpdateYes |
"更新成功" | 更新成功消息 |
CV.UpdateNo |
"更新失败" | 更新失败消息 |
CV.DeleteYes |
"删除成功" | 删除成功消息 |
CV.DeleteNo |
"删除失败" | 删除失败消息 |
CV.GetYes |
"获取成功" | 获取成功消息 |
CV.GetNo |
"获取失败" | 获取失败消息 |
CV.SecuritySchemeId |
"Bearer" | 认证方案 ID |
CV.NullValue |
null | 空值对象 |
示例代码
完整控制器示例
using Acme.ReturnOh;
using Microsoft.AspNetCore.Mvc;
namespace MyProject.Controllers
{
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet]
public Oh GetAll()
{
var users = _userService.GetAll();
return users.Success(CV.GetYes);
}
[HttpGet("{id}")]
public Oh GetById(int id)
{
var user = _userService.GetById(id);
if (user == null)
{
return CV.NullValue.Fail("用户不存在");
}
return user.Success(CV.GetYes);
}
[HttpPost]
public Oh Create([FromBody] UserDto userDto)
{
var result = _userService.Create(userDto);
return result.IsSuccess(CV.InsertYes, CV.InsertNo);
}
[HttpPut("{id}")]
public Oh Update(int id, [FromBody] UserDto userDto)
{
var result = _userService.Update(id, userDto);
return result.IsSuccess(CV.UpdateYes, CV.UpdateNo);
}
[HttpDelete("{id}")]
public Oh Delete(int id)
{
var result = _userService.Delete(id);
return result.IsSuccess(CV.DeleteYes, CV.DeleteNo);
}
}
}
服务层示例
using Acme.ReturnOh;
namespace MyProject.Services
{
public class UserService : IUserService
{
private readonly List<User> _users = new();
public List<User> GetAll()
{
return _users;
}
public User GetById(int id)
{
return _users.FirstOrDefault(u => u.Id == id);
}
public bool Create(UserDto userDto)
{
// 业务逻辑
if (string.IsNullOrEmpty(userDto.Username))
{
Oh<User>.Exception("用户名不能为空");
}
_users.Add(new User
{
Id = _users.Count + 1,
Username = userDto.Username,
Email = userDto.Email
});
return true;
}
public bool Update(int id, UserDto userDto)
{
var user = _users.FirstOrDefault(u => u.Id == id);
if (user == null)
{
Oh<User>.Exception("用户不存在");
}
user.Username = userDto.Username;
user.Email = userDto.Email;
return true;
}
public bool Delete(int id)
{
var user = _users.FirstOrDefault(u => u.Id == id);
if (user == null)
{
Oh<User>.Exception("用户不存在");
}
return _users.Remove(user);
}
}
}
多版本 Swagger 配置示例
using Acme.ReturnOh;
using Acme.ReturnOh.Dtos;
var builder = WebApplication.CreateBuilder(args);
// 配置多版本 Swagger
var swaggerDocs = new List<SwaggerDocDto>
{
new("后台管理 API", "v1"),
new("移动端 API", "v2")
};
builder.Services.ConfigureSwaggerOptions(swaggerDocs);
builder.Services.ConfigureApiBehaviorOptions();
builder.Services.AddExceptionFilterService();
builder.Services.AddControllers();
var app = builder.Build();
// 启用多版本 Swagger
app.UseBathSwagger(swaggerDocs, "swagger");
app.UseAuthorization();
app.MapControllers();
app.Run();
常见问题
1. 如何自定义异常处理逻辑?
可以创建自定义异常过滤器并通过 AddExceptionFilterService<T> 方法注册。
2. 如何修改默认的成功/失败消息?
可以在调用 Success、Fail 方法时传入自定义消息,或直接使用 CV 类中定义的常量。
3. 如何添加自定义状态码?
可以使用 Custom 方法创建自定义状态码的响应:
return data.Custom(403, "权限不足");
4. 如何在 Swagger 中显示 XML 注释?
确保项目已启用 XML 文档生成,并在 ConfigureSwaggerOptions 方法中包含相应的 XML 文件。
5. 如何禁用 JWT 认证?
在 ConfigureSwaggerOptions 方法中设置 enableJwtBearerAuth 参数为 false:
builder.Services.ConfigureSwaggerOptions("API 文档", enableJwtBearerAuth: false);
6. 如何修改 Swagger 访问路径?
在 UseSingSwagger 或 UseBathSwagger 方法中设置 routePrefix 参数:
// 根路径访问
app.UseSingSwagger("API 文档", routePrefix: "");
// 通过 /swagger 访问
app.UseSingSwagger("API 文档", routePrefix: "swagger");
// 通过 /api-docs 访问
app.UseSingSwagger("API 文档", routePrefix: "api-docs");
7. 如何禁用 API 方法排序?
在 ConfigureSwaggerOptions 方法中设置 isActionOrder 参数为 false:
builder.Services.ConfigureSwaggerOptions("API 文档", isActionOrder: false);
版本历史
- 1.7.5 - 当前版本
总结
Acme.ReturnOh 是一个简单而强大的库,为 .NET 项目提供了统一的 API 响应格式、异常处理和 Swagger 配置功能。通过使用这个库,您可以:
- 统一 API 响应格式,提高前端开发效率
- 自动处理异常,减少重复代码
- 简化参数验证错误处理
- 快速配置 Swagger 文档(支持多版本和 JWT 认证)
- 灵活的自定义异常过滤器支持
希望这个库能帮助您更高效地开发 .NET 项目!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 10.0.5)
- Swashbuckle.AspNetCore.Swagger (>= 10.1.5)
- Swashbuckle.AspNetCore.SwaggerGen (>= 10.1.5)
- Swashbuckle.AspNetCore.SwaggerUI (>= 10.1.5)
-
net8.0
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.25)
- Swashbuckle.AspNetCore.Swagger (>= 10.1.5)
- Swashbuckle.AspNetCore.SwaggerGen (>= 10.1.5)
- Swashbuckle.AspNetCore.SwaggerUI (>= 10.1.5)
-
net9.0
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 9.0.14)
- Swashbuckle.AspNetCore.Swagger (>= 10.1.5)
- Swashbuckle.AspNetCore.SwaggerGen (>= 10.1.5)
- Swashbuckle.AspNetCore.SwaggerUI (>= 10.1.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 1.7.5 | 115 | 3/27/2026 | |
| 1.7.5-beta | 108 | 3/25/2026 | |
| 1.7.4 | 109 | 3/25/2026 | |
| 1.7.3 | 161 | 3/16/2026 | |
| 1.7.2 | 156 | 1/14/2026 | |
| 1.7.1 | 200 | 12/12/2025 | |
| 1.7.0 | 188 | 11/29/2025 | |
| 1.5.0 | 235 | 1/20/2025 | |
| 1.4.5 | 188 | 11/18/2024 | |
| 1.4.3 | 173 | 11/18/2024 | |
| 1.4.2.1 | 235 | 4/12/2024 | |
| 1.4.2 | 234 | 4/7/2024 | |
| 1.4.1 | 226 | 4/7/2024 | |
| 1.4.0 | 198 | 4/2/2024 | |
| 1.3.0 | 235 | 3/29/2024 | |
| 1.2.3 | 279 | 3/18/2024 | |
| 1.2.2 | 214 | 3/18/2024 | |
| 1.2.1 | 279 | 3/18/2024 | |
| 1.1.2 | 220 | 3/18/2024 | |
| 1.1.1 | 315 | 3/18/2024 |