Acme.ReturnOh 1.7.5

dotnet add package Acme.ReturnOh --version 1.7.5
                    
NuGet\Install-Package Acme.ReturnOh -Version 1.7.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Acme.ReturnOh" Version="1.7.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Acme.ReturnOh" Version="1.7.5" />
                    
Directory.Packages.props
<PackageReference Include="Acme.ReturnOh" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Acme.ReturnOh --version 1.7.5
                    
#r "nuget: Acme.ReturnOh, 1.7.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Acme.ReturnOh@1.7.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Acme.ReturnOh&version=1.7.5
                    
Install as a Cake Addin
#tool nuget:?package=Acme.ReturnOh&version=1.7.5
                    
Install as a Cake Tool

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. 如何修改默认的成功/失败消息?

可以在调用 SuccessFail 方法时传入自定义消息,或直接使用 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 访问路径?

UseSingSwaggerUseBathSwagger 方法中设置 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 配置功能。通过使用这个库,您可以:

  1. 统一 API 响应格式,提高前端开发效率
  2. 自动处理异常,减少重复代码
  3. 简化参数验证错误处理
  4. 快速配置 Swagger 文档(支持多版本和 JWT 认证)
  5. 灵活的自定义异常过滤器支持

希望这个库能帮助您更高效地开发 .NET 项目!

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.3 is deprecated because it has critical bugs.
1.7.2 156 1/14/2026 1.7.2 is deprecated because it has critical bugs.
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.2.1 is deprecated because it has critical bugs.
1.1.2 220 3/18/2024
1.1.1 315 3/18/2024 1.1.1 is deprecated because it has critical bugs.