zoukankan      html  css  js  c++  java
  • 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,望技术有成后能回来看见自己的脚步
  • 相关阅读:
    Java.io.outputstream.PrintStream:打印流
    Codeforces 732F. Tourist Reform (Tarjan缩点)
    退役了
    POJ 3281 Dining (最大流)
    Light oj 1233
    Light oj 1125
    HDU 5521 Meeting (最短路)
    Light oj 1095
    Light oj 1044
    HDU 3549 Flow Problem (dinic模版 && isap模版)
  • 原文地址:https://www.cnblogs.com/CKExp/p/10776948.html
Copyright © 2011-2022 走看看