您现在的位置是:网站首页> 编程资料编程资料

为ABP框架添加基础集成服务_基础应用_

2023-05-24 578人已围观

简介 为ABP框架添加基础集成服务_基础应用_

定义一个特性标记

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

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

 ///  /// 标记枚举代表的信息 ///  [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 { ///  /// 标准 HTTP 状态码 /// 文档地址 ///  public enum HttpStateCode { Status412PreconditionFailed = 412, Status413PayloadTooLarge = 413, Status413RequestEntityTooLarge = 413, Status414RequestUriTooLong = 414, Status414UriTooLong = 414, Status415UnsupportedMediaType = 415, Status416RangeNotSatisfiable = 416, Status416RequestedRangeNotSatisfiable = 416, Status417ExpectationFailed = 417, Status418ImATeapot = 418, Status419AuthenticationTimeout = 419, Status421MisdirectedRequest = 421, Status422UnprocessableEntity = 422, Status423Locked = 423, Status424FailedDependency = 424, Status426UpgradeRequired = 426, Status428PreconditionRequired = 428, Status429TooManyRequests = 429, Status431RequestHeaderFieldsTooLarge = 431, Status451UnavailableForLegalReasons = 451, Status500InternalServerError = 500, Status501NotImplemented = 501, Status502BadGateway = 502, Status503ServiceUnavailable = 503, Status504GatewayTimeout = 504, Status505HttpVersionNotsupported = 505, Status506VariantAlsoNegotiates = 506, Status507InsufficientStorage = 507, Status508LoopDetected = 508, Status411LengthRequired = 411, Status510NotExtended = 510, Status410Gone = 410, Status408RequestTimeout = 408, Status101SwitchingProtocols = 101, Status102Processing = 102, Status200OK = 200, Status201Created = 201, Status202Accepted = 202, Status203NonAuthoritative = 203, Status204NoContent = 204, Status205ResetContent = 205, Status206PartialContent = 206, Status207MultiStatus = 207, Status208AlreadyReported = 208, Status226IMUsed = 226, Status300MultipleChoices = 300, Status301MovedPermanently = 301, Status302Found = 302, Status303SeeOther = 303, Status304NotModified = 304, Status305UseProxy = 305, Status306SwitchProxy = 306, Status307TemporaryRedirect = 307, Status308PermanentRedirect = 308, Status400BadRequest = 400, Status401Unauthorized = 401, Status402PaymentRequired = 402, Status403Forbidden = 403, Status404NotFound = 404, Status405MethodNotAllowed = 405, Status406NotAcceptable = 406, Status407ProxyAuthenticationRequired = 407, Status409Conflict = 409, Status511NetworkAuthenticationRequired = 511 } }

常用的请求结果

在相同目录,创建一个 CommonResponseType 枚举,其内容如下:

 ///  /// 常用的 API 响应信息 ///  public enum CommonResponseType { [SchemeName("")] Default = 0, [SchemeName("请求成功")] RequstSuccess = 1, [SchemeName("请求失败")] RequstFail = 2, [SchemeName("创建资源成功")] CreateSuccess = 4, [SchemeName("创建资源失败")] CreateFail = 8, [SchemeName("更新资源成功")] UpdateSuccess = 16, [SchemeName("更新资源失败")] UpdateFail = 32, [SchemeName("删除资源成功")] DeleteSuccess = 64, [SchemeName("删除资源失败")] DeleteFail = 128, [SchemeName("请求的数据未能通过验证")] BadRequest = 256, [SchemeName("服务器出现严重错误")] Status500InternalServerError = 512 }

响应模型

在 Apis 目录,创建一个 ApiResponseModel`.cs 泛型类文件,其内容如下:

namespace AbpBase.Domain.Shared.Apis { ///  /// API 响应格式 /// 避免滥用,此类不能实例化,只能通过预定义的静态方法生成 ///  ///  public abstract class ApiResponseModel { public HttpStateCode StatuCode { get; set; } public string Message { get; set; } public TData Data { get; set; } ///  /// 私有类 ///  ///  private class PrivateApiResponseModel : ApiResponseModel { } } }

StatuCode:用于说明此次响应的状态;

Message:响应的信息;

Data:响应的数据;

可能你会觉得这样很奇怪,先不要问,也不要猜,照着做,后面我会告诉你为什么这样写。

然后再创建一个类:

using AbpBase.Domain.Shared.Helpers; using System; namespace AbpBase.Domain.Shared.Apis { ///  /// Web 响应格式 /// 避免滥用,此类不能实例化,只能通过预定义的静态方法生成 ///  public abstract class ApiResponseModel : ApiResponseModel { ///  /// 根据枚举创建响应格式 ///  ///  ///  ///  ///  public static ApiResponseModel Create(HttpStateCode code, TEnum enumType) where TEnum : Enum { return new PrivateApiResponseModel { StatuCode = code, Message = SchemeHelper.Get(enumType), }; } ///  /// 创建标准的响应 ///  ///  ///  ///  ///  ///  ///  public static ApiResponseModel Create(HttpStateCode code, TEnum enumType, dynamic Data) { return new PrivateApiResponseModel { StatuCode = code, Message = SchemeHelper.Get(enumType), Data = Data }; } ///  /// 请求成功 ///  ///  ///  ///  public static ApiResponseModel CreateSuccess(HttpStateCode code, dynamic Data) { return new PrivateApiResponseModel { StatuCode = code, Message = "Success", Data = Data }; } ///  /// 私有类 ///  private class PrivateApiResponseModel : ApiResponseModel { } } }

同时在项目中创建一个 Helpers 文件夹,再创建一个 SchemeHelper 类,其内容如下:

using AbpBase.Domain.Shared.Attributes; using System; using System.Linq; using System.Reflection; namespace AbpBase.Domain.Shared.Helpers { ///  /// 获取各种枚举代表的信息 ///  public static class SchemeHelper { private static readonly PropertyInfo SchemeNameAttributeMessage = typeof(SchemeNameAttribute).GetProperty(nameof(SchemeNameAttribute.Message)); ///  /// 获取一个使用了 SchemeNameAttribute 特性的 Message 属性值 ///  ///  ///  ///  public static string Get(T type) { return GetValue(type); } private static string GetValue(T type) { var attr = typeof(T).GetField(Enum.GetName(type.GetType(), type)) .GetCustomAttributes() .FirstOrDefault(x => x.GetType() == typeof(SchemeNameAttribute)); if (attr == null) return string.Empty; var value = (string)SchemeNameAttributeMessage.GetValue(attr); return value; } } }

上面的类到底是干嘛的,你先不要问。

全局异常拦截器

在 AbpBase.Web 项目中,新建一个 Filters 文件夹,添加一个 WebGlobalExceptionFilter.cs 文件,其文件内容如下:

using AbpBase.Domain.Shared.Apis; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Newtonsoft.Json; using System.Threading.Tasks; namespace ApbBase.HttpApi.Filters { ///  /// Web 全局异常过滤器,处理 Web 中出现的、运行时未处理的异常 ///  public class WebGlobalExceptionFilter : IAsyncExceptionFilter { public async Task OnExceptionAsync(ExceptionContext context) { if (!context.ExceptionHandled) { ApiResponseModel model = ApiResponseModel.Create(HttpStateCode.Status500InternalServerError, CommonResponseType.Status500InternalServerError); context.Result = new ContentResult { Content = JsonConvert.SerializeObject(model), StatusCode = StatusCodes.Status200OK, ContentType = "application/json; charset=utf-8" }; } context.ExceptionHandled = true; await Task.CompletedTask; } } }

然后 在 AbpBaseWebModule 模块的 ConfigureServices 函数中,加上:

 Configure(options => { options.Filters.Add(typeof(WebGlobalExceptionFilter)); });

这里我们还没有将写入日志,后面再增加这方面的功能。

先说明一下

前面我们定义了 ApiResponseModel 和其他一些特性还有枚举,这里解释一下原因。

ApiResponseModel 是抽象类

ApiResponseModel 和 ApiResponseModel 是抽象类,是为了避免开发者使用时,直接这样用:

 ApiResponseModel mode = new ApiResponseModel { Code = 500, Message = "失败", Data = xxx };

首先这个 Code 需要按照 HTTP 状态的标准来填写,我们使用 HttpStateC

-六神源码网