当前位置: 首页 > news >正文

如何申请做网站电子商务前景怎么样

如何申请做网站,电子商务前景怎么样,阿里云备案 网站服务内容,那个网站做图片好看点击上方蓝字关注我们Abp 框架本身针对内部抛出异常进行了统一拦截#xff0c;并且针对不同的异常也会采取不同的处理策略。在 Abp 当中主要提供了以下几种异常类型#xff1a;异常类型描述AbpExceptionAbp 框架定义的基本异常类型#xff0c;Abp 所有内部定义的异常类型都继… 点击上方蓝字关注我们Abp 框架本身针对内部抛出异常进行了统一拦截并且针对不同的异常也会采取不同的处理策略。在 Abp 当中主要提供了以下几种异常类型异常类型描述AbpExceptionAbp 框架定义的基本异常类型Abp 所有内部定义的异常类型都继承自本类。AbpInitializationExceptionAbp 框架初始化时出现错误所抛出的异常。AbpDbConcurrencyException当 EF Core 执行数据库操作时产生了 DbUpdateConcurrencyException 异常的时候 Abp 会封装为本异常并且抛出。AbpValidationException用户调用接口时输入的DTO 参数有误会抛出本异常。BackgroundJobException后台作业执行过程中产生的异常。EntityNotFoundException当仓储执行 Get 操作时实体未找到引发本异常。UserFriendlyException如果用户需要将异常信息发送给前端请抛出本异常。AbpRemoteCallException远程调用一场当使用 Abp 提供的 AbpWebApiClient 产生问题的时候会抛出此异常。1.启动流程Abp 框架针对异常拦截的处理主要使用了 ASP .NET CORE MVC 过滤器机制当外部请求接口的时候所有异常都会被 Abp 框架捕获。Abp 异常过滤器的实现名称叫做 AbpExceptionFilter它在注入 Abp 框架的时候就已经被注册到了 ASP .NET Core 的 MVC Filters 当中了。1.1 流程图1.2 代码流程注入 Abp 框架处public static IServiceProvider AddAbpTStartupModule(this IServiceCollection services, [CanBeNull] ActionAbpBootstrapperOptions optionsAction null)where TStartupModule : AbpModule {var abpBootstrapper AddAbpBootstrapperTStartupModule(services, optionsAction);// 配置 ASP .NET Core 参数ConfigureAspNetCore(services, abpBootstrapper.IocManager);return WindsorRegistrationHelper.CreateServiceProvider(abpBootstrapper.IocManager.IocContainer, services); } ConfigureAspNetCore() 方法内部private static void ConfigureAspNetCore(IServiceCollection services, IIocResolver iocResolver) {// ...省略掉的其他代码// 配置 MVCservices.ConfigureMvcOptions(mvcOptions {mvcOptions.AddAbp(services);});// ...省略掉的其他代码 } AbpMvcOptionsExtensions 扩展类针对 MvcOptions 提供的扩展方法 AddAbp() public static void AddAbp(this MvcOptions options, IServiceCollection services) {AddConventions(options, services);// 添加 VC 过滤器AddFilters(options);AddModelBinders(options); } AddFilters() 方法内部private static void AddFilters(MvcOptions options) {// 权限认证过滤器options.Filters.AddService(typeof(AbpAuthorizationFilter));// 审计信息过滤器options.Filters.AddService(typeof(AbpAuditActionFilter));// 参数验证过滤器options.Filters.AddService(typeof(AbpValidationActionFilter));// 工作单元过滤器options.Filters.AddService(typeof(AbpUowActionFilter));// 异常过滤器options.Filters.AddService(typeof(AbpExceptionFilter));// 接口结果过滤器options.Filters.AddService(typeof(AbpResultFilter)); } 2.代码分析2.1 基本定义Abp 框架所提供的所有异常类型都继承自 AbpException 我们可以看一下该类型的基本定义。// Abp 基本异常定义 [Serializable] public class AbpException : Exception {public AbpException(){}public AbpException(SerializationInfo serializationInfo, StreamingContext context): base(serializationInfo, context){}// 构造函数1接受一个异常描述信息public AbpException(string message): base(message){}// 构造函数2接受一个异常描述信息与内部异常public AbpException(string message, Exception innerException): base(message, innerException){} } 类型的定义是十分简单的基本上就是继承了原有的 Exception 类型改了一个名字罢了。2.2 异常拦截Abp 本身针对异常信息的核心处理就在于它的 AbpExceptionFilter 过滤器过滤器实现很简单。它首先继承了 IExceptionFilter 接口实现了其 OnException() 方法只要用户请求接口的时候出现了任何异常都会调用 OnException() 方法。而在 OnException() 方法内部Abp 根据不同的异常类型进行了不同的异常处理。public class AbpExceptionFilter : IExceptionFilter, ITransientDependency {// 日志记录器public ILogger Logger { get; set; }// 事件总线public IEventBus EventBus { get; set; }// 错误信息构建器private readonly IErrorInfoBuilder _errorInfoBuilder;// AspNetCore 相关的配置信息private readonly IAbpAspNetCoreConfiguration _configuration;// 注入并初始化内部成员对象public AbpExceptionFilter(IErrorInfoBuilder errorInfoBuilder, IAbpAspNetCoreConfiguration configuration){_errorInfoBuilder errorInfoBuilder;_configuration configuration;Logger NullLogger.Instance;EventBus NullEventBus.Instance;}// 异常触发时会调用此方法public void OnException(ExceptionContext context){// 判断是否由控制器触发如果不是则不做任何处理if (!context.ActionDescriptor.IsControllerAction()){return;}// 获得方法的包装特性。决定后续操作,如果没有指定包装特性则使用默认特性var wrapResultAttribute ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(context.ActionDescriptor.GetMethodInfo(),_configuration.DefaultWrapResultAttribute);// 如果方法上面的包装特性要求记录日志则记录日志if (wrapResultAttribute.LogError){LogHelper.LogException(Logger, context.Exception);}// 如果被调用的方法上的包装特性要求重新包装错误信息则调用 HandleAndWrapException() 方法进行包装if (wrapResultAttribute.WrapOnError){HandleAndWrapException(context);}}// 处理并包装异常private void HandleAndWrapException(ExceptionContext context){// 判断被调用接口的返回值是否符合标准不符合则直接返回if (!ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType)){return;}// 设置 HTTP 上下文响应所返回的错误代码由具体异常决定。context.HttpContext.Response.StatusCode GetStatusCode(context);// 重新封装响应返回的具体内容。采用 AjaxResponse 进行封装context.Result new ObjectResult(new AjaxResponse(_errorInfoBuilder.BuildForException(context.Exception),context.Exception is AbpAuthorizationException));// 触发异常处理事件EventBus.Trigger(this, new AbpHandledExceptionData(context.Exception));// 处理完成将异常上下文的内容置为空context.Exception null; //Handled!}// 根据不同的异常类型返回不同的 HTTP 错误码protected virtual int GetStatusCode(ExceptionContext context){if (context.Exception is AbpAuthorizationException){return context.HttpContext.User.Identity.IsAuthenticated? (int)HttpStatusCode.Forbidden: (int)HttpStatusCode.Unauthorized;}if (context.Exception is AbpValidationException){return (int)HttpStatusCode.BadRequest;}if (context.Exception is EntityNotFoundException){return (int)HttpStatusCode.NotFound;}return (int)HttpStatusCode.InternalServerError;} } 以上就是 Abp 针对异常处理的具体操作了在这里面涉及到的 WrapResultAttribute 、 AjaxResponse 、 IErrorInfoBuilder 都会在后面说明但是具体的逻辑已经在过滤器所体现了。2.3 接口返回值包装Abp 针对所有 API 返回的数据都会进行一次包装使得其返回值内容类似于下面的内容。{result: {totalCount: 0,items: []},targetUrl: null,success: true,error: null,unAuthorizedRequest: false,__abp: true } 其中的 result 节点才是你接口真正返回的内容其余的 targetUrl 之类的都是属于 Abp 包装器给你进行封装的。2.3.1 包装器特性其中Abp 预置的包装器有两种第一个是 WrapResultAttribute 。它有两个 bool 类型的参数默认均为 true 一个叫 WrapOnSuccess 一个 叫做 WrapOnError 分别用于确定成功或则失败后是否包装具体信息。像之前的 OnException() 方法里面就有用该值进行判断是否包装异常信息。除了 WarpResultAttribute 特性还有一个 DontWrapResultAttribute 的特性该特性直接继承自 WarpResultAttribute 只不过它的 WrapOnSuccess 与 WrapOnError 都为 fasle 状态也就是说无论接口调用结果是成功还是失败都不会进行结果包装。该特性可以直接打在接口方法、控制器、接口之上类似于这样public class TestApplicationService : ApplicationService {[DontWrapResult]public async Taskstring Get(){return await Task.FromResult(Hello World);} } 那么这个接口的返回值就不会带有其他附加信息而直接会按照 Json 来序列化返回你的对象。在拦截异常的时候如果你没有给接口方法打上 DontWarpResult 特性那么他就会直接使用 IAbpAspNetCoreConfiguration 的 DefaultWrapResultAttribute 属性指定的默认特性该默认特性如果没有显式指定则为 WrapResultAttribute 。public AbpAspNetCoreConfiguration() {DefaultWrapResultAttribute new WrapResultAttribute();// ...IAbpAspNetCoreConfiguration 的默认实现的构造函数// ...省略掉了其他代码 } 2.3.2 具体包装行为Abp 针对正常的接口数据返回与异常数据返回都是采用的 AjaxResponse 来进行封装的转到其基类的定义可以看到在里面定义的那几个属性就是我们接口返回出来的数据。public abstract class AjaxResponseBase {// 目标 Url 地址public string TargetUrl { get; set; }// 接口调用是否成功public bool Success { get; set; }// 当接口调用失败时错误信息存放在此处public ErrorInfo Error { get; set; }// 是否是未授权的请求public bool UnAuthorizedRequest { get; set; }// 用于标识接口是否基于 Abp 框架开发public bool __abp { get; } true; } So从刚才的 2.2 节 可以看到他是直接 new 了一个 AjaxResponse 对象然后使用 IErrorInfoBuilder 来构建了一个 ErrorInfo 错误信息对象传入到 AjaxResponse 对象当中并且返回。那么问题来了这里的 IErrorInfoBuilder 是怎样来进行包装的呢2.3.3 异常包装器当 Abp 捕获到异常之后会通过 IErrorInfoBuilder 的 BuildForException() 方法来将异常转换为 ErrorInfo 对象。它的默认实现只有一个就是 ErrorInfoBuilder 内部结构也很简单其 BuildForException() 方法直接通过内部的一个转换器进行转换也就是 IExceptionToErrorInfoConverter直接调用的 IExceptionToErrorInfoConverter.Convert() 方法。同时它拥有另外一个方法叫做 AddExceptionConverter()可以传入你自己实现的异常转换器。public class ErrorInfoBuilder : IErrorInfoBuilder, ISingletonDependency {private IExceptionToErrorInfoConverter Converter { get; set; }public ErrorInfoBuilder(IAbpWebCommonModuleConfiguration configuration, ILocalizationManager localizationManager){// 异常包装器默认使用的 DefaultErrorInfoConverter 来进行转换Converter new DefaultErrorInfoConverter(configuration, localizationManager);}// 根据异常来构建异常信息public ErrorInfo BuildForException(Exception exception){return Converter.Convert(exception);}// 添加用户自定义的异常转换器public void AddExceptionConverter(IExceptionToErrorInfoConverter converter){converter.Next Converter;Converter converter;} } 2.3.4 异常转换器Abp 要包装异常具体的操作是由转换器来决定的Abp 实现了一个默认的转换器叫做 DefaultErrorInfoConverter在其内部注入了 IAbpWebCommonModuleConfiguration 配置项而用户可以通过配置该选项的 SendAllExceptionsToClients 属性来决定是否将异常输出给客户端。我们先来看一下他的 Convert() 核心方法public ErrorInfo Convert(Exception exception) {// 封装 ErrorInfo 对象var errorInfo CreateErrorInfoWithoutCode(exception);// 如果具体的异常实现有 IHasErrorCode 接口则将错误码也封装到 ErrorInfo 对象内部if (exception is IHasErrorCode){errorInfo.Code (exception as IHasErrorCode).Code;}return errorInfo; } 核心十分简单而 CreateErrorInfoWithoutCode() 方法内部呢也是一些具体的逻辑根据异常类型的不同执行不同的转换逻辑。private ErrorInfo CreateErrorInfoWithoutCode(Exception exception) {// 如果要发送所有异常则使用 CreateDetailedErrorInfoFromException() 方法进行封装if (SendAllExceptionsToClients){return CreateDetailedErrorInfoFromException(exception);}// 如果有多个异常并且其内部异常为 UserFriendlyException 或者 AbpValidationException 则将内部异常拿出来放在最外层进行包装if (exception is AggregateException exception.InnerException ! null){var aggException exception as AggregateException;if (aggException.InnerException is UserFriendlyException ||aggException.InnerException is AbpValidationException){exception aggException.InnerException;}}// 如果一场类型为 UserFriendlyException 则直接通过 ErrorInfo 构造函数进行构建if (exception is UserFriendlyException){var userFriendlyException exception as UserFriendlyException;return new ErrorInfo(userFriendlyException.Message, userFriendlyException.Details);}// 如果为参数类一场则使用不同的构造函数进行构建并且在这里可以看到他通过 L 函数调用的多语言提示if (exception is AbpValidationException){return new ErrorInfo(L(ValidationError)){ValidationErrors GetValidationErrorInfos(exception as AbpValidationException),Details GetValidationErrorNarrative(exception as AbpValidationException)};}// 如果是实体未找到的异常则包含具体的实体类型信息与实体 ID 值if (exception is EntityNotFoundException){var entityNotFoundException exception as EntityNotFoundException;if (entityNotFoundException.EntityType ! null){return new ErrorInfo(string.Format(L(EntityNotFound),entityNotFoundException.EntityType.Name,entityNotFoundException.Id));}return new ErrorInfo(entityNotFoundException.Message);}// 如果是未授权的一场一样的执行不同的操作if (exception is Abp.Authorization.AbpAuthorizationException){var authorizationException exception as Abp.Authorization.AbpAuthorizationException;return new ErrorInfo(authorizationException.Message);}// 除了以上这几个固定的异常需要处理之外其他的所有异常统一返回内部服务器错误信息。return new ErrorInfo(L(InternalServerError)); } 所以整体异常处理还是比较复杂的进行了多层封装但是结构还是十分清晰的。3.扩展3.1 显示额外的异常信息如果你需要在调用接口而产生异常的时候展示异常的详细信息可以通过在启动模块的 PreInitialize() (预加载方法) 当中加入 Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients true; 即可例如[DependsOn(typeof(AbpAspNetCoreModule))] public class TestWebStartupModule : AbpModule {public override void PreInitialize(){Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients true;} } 3.2 监听异常事件使用 Abp 框架的时候你可以随时通过监听 AbpHandledExceptionData 事件来使用自己的逻辑处理产生的异常。比如说产生异常时向监控服务报警或者说将异常信息持久化到其他数据库等等。你只需要编写如下代码即可实现监听异常事件public class ExceptionEventHandler : IEventHandlerAbpHandledExceptionData, ITransientDependency {/// summary/// Handler handles the event by implementing this method./// /summary/// param nameeventDataEvent data/parampublic void HandleEvent(AbpHandledExceptionData eventData){Console.WriteLine($当前异常信息为{eventData.Exception.Message});} } 如果你觉得看的有点吃力的话可以跳转到 这里 了解 Abp 的事件总线实现。作者myzony出处https://www.cnblogs.com/myzony/p/9460021.html公众号“码侠江湖”所发表内容注明来源的版权归原出处所有无法查证版权的或者未注明出处的均来自网络系转载转载的目的在于传递更多信息版权属于原作者。如有侵权请联系笔者会第一时间删除处理扫描二维码获取更多精彩码侠江湖
http://www.pierceye.com/news/759141/

相关文章:

  • 常德网站建设套餐报价英文网站字体大小
  • 橙色网站logo 配色播放器网站怎么做
  • dw网站制作怎样做网站xml
  • 房屋租赁网站开发意义新网站如何做排名
  • 钉钉如何做自己的网站银川企业网站建设
  • 做游戏女角色去衣的网站网站建设及售后服务的说明书
  • 微网站下载资料怎么做网站开发毕业设计任务书怎么写
  • ckplayer网站根目录泉州 网站制作
  • 中国建设银行网站江苏分行帮别人做网站收多少钱合适
  • 公司该建哪种网站带有互动的网站开发
  • 怎样进入谷歌网站怎么做一个简易网站
  • 邯郸网站优化公司集团公司简介模板
  • 网站的需求分析怎么写文山州住房建设网站
  • 广东网站开发费用动易的网站能否静态
  • 网站的后期维护php建设图书网站代码
  • 做营销网站制作外贸多语言网站建设
  • 广州做网站 信科网络wordpress优化宝塔
  • 深圳网站制作作枣庄做网站制作
  • 企业做网站方案建筑公司网站平台
  • 简单的企业网站phpwordpress 图标插件
  • 网页界面设计评分标准东营网站关键字优化
  • 手表网站背景素材玉山网站建设
  • 增城新塘网站建设温州网站推广效果
  • 东莞市住房建设局网站编程能干什么
  • asp做一个简单网站推广图片素材
  • 新网站一直不被收录wordpress 视频 广告
  • 网站建设费账务处理一个小胖子从网站做任务的网站故事
  • 国外被墙网站东营建设信息网最新消息
  • iphone下载网页视频北京百度seo排名公司
  • 怎么自己做网站免费的衡阳seo网站推广