如何为ABP框架集成基础服务实现功能扩展?

2026-03-30 11:091阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1676个文字,预计阅读时间需要7分钟。

如何为ABP框架集成基础服务实现功能扩展?

目录- 定义一个特性标记- 全局系统消息格式- Http 状态码- 常用的请求结果- 响应模型- ApiResponseModel 是抽象类- 跨域请求- 配置 API 服务- 统一 API 模型验证- 创建

目录
  • 定义一个特性标记
  • 全局统一消息格式
    • Http 状态码
    • 常用的请求结果
    • 响应模型
    • 全局异常拦截器
  • 先说明一下
    • ApiResponseModel 是抽象类
    • 跨域请求
    • 配置 API 服务
  • 统一 API 模型验证消息
    • 创建前
    • 创建方式
    • 创建后
  • 补充:为什么需要统一格式

    定义一个特性标记

    这个标记用于标记一个枚举代表的信息。

    AbpBase.Domain.Shared项目,创建Attributes目录,然后创建一个SchemeNameAttribute类,其内容如下:

    /// <summary> /// 标记枚举代表的信息 /// </summary> [AttributeUsage(AttributeTargets.Field)] public class SchemeNameAttribute : Attribute { public string Message { get; set; } public SchemeNameAttribute(string message) { Message = message; } }

    全局统一消息格式

    为了使得 Web 应用统一响应格式以及方便编写 API 时有一个统一的标准,我们需要定义一个合适的模板。

    AbpBase.Domain.Shared创建一个Apis目录。

    Http 状态码

    为了适配各种 HTTP 请求的响应状态,我们定义一个识别状态码的枚举。

    Apis目录,创建一个HttpStateCode.cs文件,其内容如下:

    namespace AbpBase.Domain.Shared.Apis { /// <summary> /// 标准 HTTP 状态码 /// <para>文档地址<inheritdoc cref="www.runoob.com/tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|af964c79-41367b2145701111." }

    这样的信息阅读起来十分不友好,前端对接也会有一定的麻烦。

    这个时候我们可以统一模型验证拦截器,定义一个友好的响应格式。

    创建方式

    AbpBase.Web的项目 的Filters文件夹中,创建一个InvalidModelStateFilter文件,其文件内容如下:

    using AbpBase.Domain.Shared.Apis; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using System.Linq; namespace AbpBase.Web.Filters { public static class InvalidModelStateFilter { /// <summary> /// 统一模型验证 /// <para>控制器必须添加 [ApiController] 才能被此过滤器拦截</para> /// </summary> /// <param name="services"></param> public static void GlabalInvalidModelStateFilter(this IServiceCollection services) { services.Configure<ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = actionContext => { if (actionContext.ModelState.IsValid) return new BadRequestObjectResult(actionContext.ModelState); int count = actionContext.ModelState.Count; ValidationErrors[] errors = new ValidationErrors[count]; int i = 0; foreach (var item in actionContext.ModelState) { errors[i] = new ValidationErrors { Member = item.Key, Messages = item.Value.Errors?.Select(x => x.ErrorMessage).ToArray() }; i++; } // 响应消息 var result = ApiResponseModel.Create(HttpStateCode.Status400BadRequest, CommonResponseType.BadRequest, errors); var objectResult = new BadRequestObjectResult(result); objectResult.StatusCode = StatusCodes.Status400BadRequest; return objectResult; }; }); } /// <summary> /// 用于格式化实体验证信息的模型 /// </summary> private class ValidationErrors { /// <summary> /// 验证失败的字段 /// </summary> public string Member { get; set; } /// <summary> /// 此字段有何种错误 /// </summary> public string[] Messages { get; set; } } } }

    ConfigureServices函数中,添加以下代码:

    // 全局 API 请求实体验证失败信息格式化 context.Services.GlabalInvalidModelStateFilter();

    创建后

    让我们看看增加了统一模型验证器后,同样的请求返回的消息。

    请求:

    { "Id": "1", "Iphone": 123456789001234567890, "Message": null }

    返回:

    { "statuCode": 400, "message": "请求的数据未能通过验证", "data": [ { "member": "Iphone", "messages": [ "JSON integer 123456789001234567890 is too large or small for an Int32. Path 'Iphone', line 3, position 35." ] } ] }

    说明我们的统一模型验证响应起到了作用。

    但是有些验证会直接报异常而不会流转到上面的拦截器中,有些模型验证特性用错对象的话,他会报错异常的。例如上面的 MaxLength ,已经用错了,MaxLength 是指定属性中允许的数组或字符串数据的最大长度,不能用在 int 类型上。大家测试一下请求下面的 json,会发现报异常。

    { "Id": 1, "Iphone": 1234567900, "Message": "nullable" }

    以下是一些 ASP.NET Core 内置验证特性,大家记得别用错:

    • [CreditCard]:验证属性是否具有信用卡格式。 需要 JQuery 验证其他方法。
    • [Compare]:验证模型中的两个属性是否匹配。
    • [EmailAddress]:验证属性是否具有电子邮件格式。
    • [Phone]:验证属性是否具有电话号码格式。
    • [Range]:验证属性值是否在指定的范围内。
    • [RegularExpression]:验证属性值是否与指定的正则表达式匹配。
    • [Required]:验证字段是否不为 null。 有关此属性的行为的详细信息
    • [StringLength]:验证字符串属性值是否不超过指定长度限制。
    • [Url]:验证属性是否具有 URL 格式。
    • [Remote]:通过在服务器上调用操作方法来验证客户端上的输入。
    • [MaxLength ]MaxLength 是指定属性中允许的数组或字符串数据的最大长度

    参考:docs.microsoft.com/zh-cn/dotnet/api/system.componentmodel.dataannotations?view=netcore-3.1

    如何为ABP框架集成基础服务实现功能扩展?

    本系列第二篇到此,接下来第三篇会继续添加一些基础服务。

    补充:为什么需要统一格式

    首先,你看一下这样的代码:

    在每个 Action 中,都充满了这种写法,每个相同的验证问题,在每个 Action 返回的文字都不一样,没有规范可言。一个人写一个 return,就加上一下自己要表达的文字,一个项目下来,多少return?全是这种代码,不堪入目。

    通过统一模型验证和统一消息返回格式,就可以避免这些情况。

    源码地址:github.com/whuanle/AbpBaseStruct

    本教程结果代码位置:github.com/whuanle/AbpBaseStruct/tree/master/src/2/AbpBase

    到此这篇关于为ABP框架添加基础集成服务的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

    本文共计1676个文字,预计阅读时间需要7分钟。

    如何为ABP框架集成基础服务实现功能扩展?

    目录- 定义一个特性标记- 全局系统消息格式- Http 状态码- 常用的请求结果- 响应模型- ApiResponseModel 是抽象类- 跨域请求- 配置 API 服务- 统一 API 模型验证- 创建

    目录
    • 定义一个特性标记
    • 全局统一消息格式
      • Http 状态码
      • 常用的请求结果
      • 响应模型
      • 全局异常拦截器
    • 先说明一下
      • ApiResponseModel 是抽象类
      • 跨域请求
      • 配置 API 服务
    • 统一 API 模型验证消息
      • 创建前
      • 创建方式
      • 创建后
    • 补充:为什么需要统一格式

      定义一个特性标记

      这个标记用于标记一个枚举代表的信息。

      AbpBase.Domain.Shared项目,创建Attributes目录,然后创建一个SchemeNameAttribute类,其内容如下:

      /// <summary> /// 标记枚举代表的信息 /// </summary> [AttributeUsage(AttributeTargets.Field)] public class SchemeNameAttribute : Attribute { public string Message { get; set; } public SchemeNameAttribute(string message) { Message = message; } }

      全局统一消息格式

      为了使得 Web 应用统一响应格式以及方便编写 API 时有一个统一的标准,我们需要定义一个合适的模板。

      AbpBase.Domain.Shared创建一个Apis目录。

      Http 状态码

      为了适配各种 HTTP 请求的响应状态,我们定义一个识别状态码的枚举。

      Apis目录,创建一个HttpStateCode.cs文件,其内容如下:

      namespace AbpBase.Domain.Shared.Apis { /// <summary> /// 标准 HTTP 状态码 /// <para>文档地址<inheritdoc cref="www.runoob.com/tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|af964c79-41367b2145701111." }

      这样的信息阅读起来十分不友好,前端对接也会有一定的麻烦。

      这个时候我们可以统一模型验证拦截器,定义一个友好的响应格式。

      创建方式

      AbpBase.Web的项目 的Filters文件夹中,创建一个InvalidModelStateFilter文件,其文件内容如下:

      using AbpBase.Domain.Shared.Apis; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using System.Linq; namespace AbpBase.Web.Filters { public static class InvalidModelStateFilter { /// <summary> /// 统一模型验证 /// <para>控制器必须添加 [ApiController] 才能被此过滤器拦截</para> /// </summary> /// <param name="services"></param> public static void GlabalInvalidModelStateFilter(this IServiceCollection services) { services.Configure<ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = actionContext => { if (actionContext.ModelState.IsValid) return new BadRequestObjectResult(actionContext.ModelState); int count = actionContext.ModelState.Count; ValidationErrors[] errors = new ValidationErrors[count]; int i = 0; foreach (var item in actionContext.ModelState) { errors[i] = new ValidationErrors { Member = item.Key, Messages = item.Value.Errors?.Select(x => x.ErrorMessage).ToArray() }; i++; } // 响应消息 var result = ApiResponseModel.Create(HttpStateCode.Status400BadRequest, CommonResponseType.BadRequest, errors); var objectResult = new BadRequestObjectResult(result); objectResult.StatusCode = StatusCodes.Status400BadRequest; return objectResult; }; }); } /// <summary> /// 用于格式化实体验证信息的模型 /// </summary> private class ValidationErrors { /// <summary> /// 验证失败的字段 /// </summary> public string Member { get; set; } /// <summary> /// 此字段有何种错误 /// </summary> public string[] Messages { get; set; } } } }

      ConfigureServices函数中,添加以下代码:

      // 全局 API 请求实体验证失败信息格式化 context.Services.GlabalInvalidModelStateFilter();

      创建后

      让我们看看增加了统一模型验证器后,同样的请求返回的消息。

      请求:

      { "Id": "1", "Iphone": 123456789001234567890, "Message": null }

      返回:

      { "statuCode": 400, "message": "请求的数据未能通过验证", "data": [ { "member": "Iphone", "messages": [ "JSON integer 123456789001234567890 is too large or small for an Int32. Path 'Iphone', line 3, position 35." ] } ] }

      说明我们的统一模型验证响应起到了作用。

      但是有些验证会直接报异常而不会流转到上面的拦截器中,有些模型验证特性用错对象的话,他会报错异常的。例如上面的 MaxLength ,已经用错了,MaxLength 是指定属性中允许的数组或字符串数据的最大长度,不能用在 int 类型上。大家测试一下请求下面的 json,会发现报异常。

      { "Id": 1, "Iphone": 1234567900, "Message": "nullable" }

      以下是一些 ASP.NET Core 内置验证特性,大家记得别用错:

      • [CreditCard]:验证属性是否具有信用卡格式。 需要 JQuery 验证其他方法。
      • [Compare]:验证模型中的两个属性是否匹配。
      • [EmailAddress]:验证属性是否具有电子邮件格式。
      • [Phone]:验证属性是否具有电话号码格式。
      • [Range]:验证属性值是否在指定的范围内。
      • [RegularExpression]:验证属性值是否与指定的正则表达式匹配。
      • [Required]:验证字段是否不为 null。 有关此属性的行为的详细信息
      • [StringLength]:验证字符串属性值是否不超过指定长度限制。
      • [Url]:验证属性是否具有 URL 格式。
      • [Remote]:通过在服务器上调用操作方法来验证客户端上的输入。
      • [MaxLength ]MaxLength 是指定属性中允许的数组或字符串数据的最大长度

      参考:docs.microsoft.com/zh-cn/dotnet/api/system.componentmodel.dataannotations?view=netcore-3.1

      如何为ABP框架集成基础服务实现功能扩展?

      本系列第二篇到此,接下来第三篇会继续添加一些基础服务。

      补充:为什么需要统一格式

      首先,你看一下这样的代码:

      在每个 Action 中,都充满了这种写法,每个相同的验证问题,在每个 Action 返回的文字都不一样,没有规范可言。一个人写一个 return,就加上一下自己要表达的文字,一个项目下来,多少return?全是这种代码,不堪入目。

      通过统一模型验证和统一消息返回格式,就可以避免这些情况。

      源码地址:github.com/whuanle/AbpBaseStruct

      本教程结果代码位置:github.com/whuanle/AbpBaseStruct/tree/master/src/2/AbpBase

      到此这篇关于为ABP框架添加基础集成服务的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。