Controller
类与构造方法
Controller
类需要继承于ApiControllerBase
抽象类,该类为Controller下提供一系列返回方法和处理。
对应Controller的构造方法里可以接收所需要业务领域的Service
和Logger
,具体写法如下
public class IpVisitPrePayController : ApiControllerBase
{
private readonly IpVisitPrePayService _ipVisitPrePayService;
private readonly ILogger _logger;
public IpVisitPrePayController(IpVisitPrePayService ipVisitPrePayService, ILogger<IpVisitPrePayController> logger)
{
this._ipVisitPrePayService = ipVisitPrePayService;
_logger = logger;
}
// 控制器代码...
}
API方法
对应API应当标识请求方法类型和具体路由路径,如[HttpPost]
和[Route("GetIpVisitPrePay")]
,也可以合到一起写作[HttpPost("GetIpVisitPrePay")]
。如下面的方法。
目前开放的请求方法类型只有HttpGet
和HttpPost
[HttpGet("GetIpVisitPrePay")]
public async Task<ApiResponse> GetIpVisitPrePay(long seq)
{
var data = await _ipVisitPrePayService.GetIpVisitPrePay(seq);
if (data != null)
{
return SuccessResult(data);
}
else
{
return FaliedResult("未查询到相关信息");
}
}
Request 请求
Controller层下的任何对外公开的接口方法的入参都应该遵守如下方案
- 简单入参,如id等直接使用id即可。
- 复杂入参,统一建立请求类,请求统一使用
record
标注为记录类型。同时命名为方法名+Request
的名称,例如GetInvoicePageRequest
,该类存放在该业务领域对应的Dto
项目下的Requests
文件夹下 - 入参应该是完全隔离于数据库的类,没有特殊情况,不允许传入像是
IsDeleted
,CreateTime
,UpdateTime
等数据库字段。可以理解为业务用的请求类。/// <summary> /// 获取用户列表 /// </summary> [HttpPost("GetUsers")] public async Task<ApiResponse> GetUsers(GetUsersRequest request)
Request记录构造如下所示,注意事项如下:
- 统一使用
record
标注,能减小存储开销,降低GC成本。 - 尽量使用
init
而不是set
。防止前端参数被篡改。 - 使用
<summary>
头标注注释 - 对入参进行基本验证,使用Validator类即可,具体命名就是Request记录名+
Validator
,继承AbstractValidator<T>
,其中泛型T标注为记录自身。该验证类会在Controller请求中直接验证,如果验证失败会直接返回前端Code=105,MessageType=40的错误消息。(返回结果请参考下面的Response 响应段落) - Validator使用
FluentValidation
方法实现,该类直接写在record记录下即可。具体可参考FluentValidation使用手册。
/// <summary>
/// 获取用户列表请求
/// </summary>
public record GetUsersRequest
{
/// <summary>
/// 名字
/// </summary>
public string Name { get; init; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; init; }
}
public class GetUserRequestValidator : AbstractValidator<GetUsersRequest>
{
public GetUserRequestValidator()
{ RuleFor(x => x.Name)
.NotEmpty()
.WithMessage("姓名不能为空");
RuleFor(x => x.Age)
.Must(x => x >= 0 && x < 200)
.WithMessage("请输入正常年龄");
}
Request Attribute 请求属性
在HttpPost
的情况下,不带任何标记的参数默认是从Body传入的,如果需要获取Query上的参数,则需要标记为[FromQuery]
,如果同时需要Body和Query里的参数,可以写成这样。
public async Task<ApiResponse> GetUsers(GetUsersRequest request, [FromQuery] UsersFilterRequest filter)
Response 响应
ApiResponse
无论是异步方法还是同步方法,请确保在Controller层下对外公开接口方法统一使用ApiResponse
作为返回的响应类。
该响应类包含以下基本字段。
public record ApiResponse
{
/// <summary>
/// 响应码
/// </summary>
public int Code { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
/// <summary>
/// 响应消息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 结果
/// </summary>
public T Result { get; set; }
}
响应码
Code可以传入任意数字,但以下数字已被框架枚举占用。
Code | 枚举名 | 说明 |
---|---|---|
200 | Success | 成功 |
201 | Tips | 成功但包含提醒(常用于成功返回,但包含提醒) |
401 | UnAuthorized | 未授权(Token已过期) |
405 | NotAllowed | 不允许执行(该Token不允许执行该接口) |
100 | Failed | 失败 |
105 | ParametersWrong | 参数验证失败 |
消息类型
MessageType目前只支持以下四种消息类型
MessageType | 枚举名 | 中文名 | 说明 |
---|---|---|---|
10 | Notice | 提醒 | 框架捕获错误,展示在页面右上方,用户点击后关闭;默认框架捕获后的消息是"程序错误,请联系系统管理员",并且将异常信息保存到日志里 |
20 | Message | 消息框 | 页面三秒自动消失,业务流程操作过程中提供给用户反馈,展示在页面正上方;例如:入院办理成功,提示相关 |
30 | Confirm | 确认框 | 核心错误消息,需要用户手动点击确认;展示在页面中间;例如:后端业务错误 |
40 | Ignore | 忽略 | 前端忽略消息弹框,不进行任何提示;例如:查询成功,新增成功等 |
响应方法
在返回结果时,ApiControllerBase
类为当前控制器提供了一系列的简单响应方法。
方法名 | 中文名 | 说明 |
---|---|---|
SuccessResult | 成功结果 | 成功返回调用的方法,会默认返回Code=200,MessageType=40的ApiResponse |
SuccessListResult | 成功列表结果 | 成功返回的分页结果,也是Code=200,MessageType=40 |
FailedResult | 失败结果 | 失败返回的结果,框架捕获到异常也会返回该结果,默认情况下是返回Code=100,MessageType=10 |
CallResult | 直接调用服务结果 | 快速处理ServiceResult,自动判断该返回SuccessResult还是FailedResult,注意该方法不会返回SuccessListResult |
[HttpPost("GetUsers")]
public async Task<ApiResponse> GetUsers(GetUsersRequest request)
{
var users = _userService.GetUsers();
return SuccessResult(users);
}