• ABP框架展示异常信息


      接触ABP框架有一段时间了,也遇到了一些问题,看了官网文档,但是或许是看的不够细致的原因,实际开发中还是遇到了一些问题,耗费了时间去处理,回头一看,原来文档中早已提及。

      开发环境:ABP+MPA模式+Asp.Net Core

    一、异常信息处理

      犹如ABP官网文档所介绍的,ABP已经帮我们把异常这块处理的很完善了,我们要做的就是利用好ABP处理异常的功能。

       

      ABP提供了直接将应用层对外服务的功能,通过ABP运行时所创建的动态API层,我们可以使用js方法去直接调用应用层服务,当然直接访问控制器下的方法并没有被舍弃。

      

      在ABP内自动封装好了一批处理异常的类,配合着这些异常类的使用,ABP在前端也封装了一些方法,方便我们处理异常信息,同时我们也可以改造前端在展示异常的方式,ABP封装的是使用Message API展示异常信息并使用的是sweetAlert插件,ABP前端js中提供了方式可以使得我们阻止默认的展示,进而使用自定义的展示插件和展示方式。

      

       在封装的类中,UserFriendlyException是对用户友好的,对于一些操作可能产生的问题,可以通过抛出UserFriendlyException直接展示给用户看,而对于其它异常,前端会将详细信息的隐藏,因为用户并不会关心具体报错原因,只知道是报错了。在代码中,有些操作可能需要我们进行判断,然后反馈给用户,以便提示用户更改相关数据。

    [AbpAuthorize(AppPermissions.Pages_Standard_ItemCode_Create)]
    private async Task CreateItemCodeAsync(CreateOrUpdateItemCodeInput input)
    {
        var itemCode = ObjectMapper.Map<ItemCode>(input.ItemCode);
        itemCode.Id = itemCode.CreateUniqueItemCode();
    
        var existedItemCode = await _itemCodeRepository.FirstOrDefaultAsync(t => t.Id.Equals(itemCode.Id));
        if (existedItemCode != null)
        {
            throw new UserFriendlyException(L("该检测项目已经存在."));
        }
    
        await _itemCodeRepository.InsertAsync(itemCode);
    }

      如上,在做一个操作前,可能需要判断是否有相同的记录,如果有,需要提示给用户,通过直接抛出UserFriendlyException,在控制器内或在应用层抛出异常都行,可以将信息直接呈现给用户,但是需要注意的是有一些条件限制,需要满足相关的条件才能获取到该错误信息,否则很有可能拿到如下结果或是英文错误:"An error has occurred! Error detail not sent by server."

      

    二、展示异常信息的方式

      在ABP文档中,专门有一篇文章是处理异常的,https://aspnetboilerplate.com/Pages/Documents/Handling-Exceptions

       

      1、非Ajax请求,则直接展示错误页,此处模拟抛出两种异常类型,然后在界面中看异常信息。

    public IActionResult Index()
    {
        //throw new System.Exception("error message");
        throw new UserFriendlyException("error message");
    }

      如果是抛出的异常不是UserFriendlyException类型,则错误页中展示的信息可能会被隐藏,展示的是描述性的,只需要知道内部出错就行。

      

      当抛出的是UserFriendlyException类型时,可以看到一些直观的错误信息。

      

      当然,可以在WebCoreModule模块的预加载方法中启动展示详细信息。

    Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;

       比如开启后,可以看到如下具体错误信息,虽然这些信息对于用户来讲是没有什么价值的。

      

      2、Ajax请求中,跟着官方给定的文档走一遍是没有错的,就怕一些小细节没有把握到,然后产生大问题,Ajax形式的调用并结合WrapResult特性使用后,在出现异常时,会将数据封装成如下简约形式。

    {
      "targetUrl": null,
      "result": null,
      "success": false,
      "error": {
        "message": "An internal error occurred during your request!",
        "details": "..."
      },
      "unAuthorizedRequest": false
    }

       这里需要注意一个关键的一点,是调用控制器下某个方法的返回类型,必须要object、JsonResult和ObjectResult类型,否则将会页面错误框中看不到具体的错误信息。

      

      从开发习惯来讲,控制器中的方法返回值类型,我喜欢写如下的格式(错误用法),直接使用IActionResult很方便,但是也会有麻烦,

    [HttpPost]
    public async Task<IActionResult> CreateXXX([FromBody]ItemCodeViewModel itemCodeViewModel)
    {
      //do something...return Json(xxx)); }

       当在中抛出异常或是方法内调用应用层服务内抛出异常时,界面上的方法总是无法获取到异常信息,通过查看浏览器内响应的内容总是只会有错误页响应回来,而页面内只能看到"An error has occurred! Error detail not sent by server."

      

      具体原因就是这个方法的返回值不符合ABP文档给定的要求,而这些细节,在初看文档或是二次看文档中都没有发现它,细节很重要!!!

      3、直接通过动态Api层请求应用层服务,这种情形下,当应用层抛出异常时,会将异常信息经WrapResult封装,在前端获取的错误信息便是直接封装完毕的错误信息,然后再经处理展示到页面中。

    2019-04-27,望技术有成后能回来看见自己的脚步
  • 相关阅读:
    Response.AddHeader
    动态生成Excel到客户端
    java多线程编程核心技术
    Centos7安装mysql8(tar)
    linux下载安装tomcat+jdk
    cmd中传递参数运行java程序
    Java(静态)变量和(静态)代码块的执行顺序
    web(war)工程引用另一个web工程(jar包)
    转换一个字段中含有多个另外一张表的id | | 行转列
    hdu2046骨牌铺方格
  • 原文地址:https://www.cnblogs.com/CKExp/p/10776948.html
Copyright © 2020-2023  润新知