ABP throw UserFriendlyException() 源碼


ABP  throw UserFriendlyException() ,會讓前端彈出界面。

實現的話,首先 throw UserFriendlyException()  並不會在后端產生真正的異常,否則就是500 錯誤了。

ABP 的默認實現,是所有的請求,包裹在result { },里面,這個是ABP 封裝的(可以去掉)

這個是怎么在前端解析出來實際的響應內容呢?  前端有 abpHttpInterceptor.js  這在前端啟動的時候注冊的一個HttpInterceptor。

里面有這個方法,來解析出來實際的 response.  這個Interceptor 會在發送請求的時候攔截,響應回來的時候攔截,也相當於一節管道了。

 1 AbpHttpConfiguration.prototype.handleAbpResponse = function (response, ajaxResponse) {
 2         var newResponse;
 3         if (ajaxResponse.success) {
 4             newResponse = response.clone({
 5                 body: ajaxResponse.result
 6             });
 7             if (ajaxResponse.targetUrl) {
 8                 this.handleTargetUrl(ajaxResponse.targetUrl);
 9                 ;
10             }
11         }
12         else {
13             newResponse = response.clone({
14                 body: ajaxResponse.result
15             });
16             if (!ajaxResponse.error) {
17                 ajaxResponse.error = this.defaultError;
18             }
19             this.logError(ajaxResponse.error);
20             this.showError(ajaxResponse.error);
21             if (response.status === 401) {
22                 this.handleUnAuthorizedRequest(null, ajaxResponse.targetUrl);
23             }
24         }
25         return newResponse;
26     };

 再來看后端怎么實現的。

后端有一個AbpMvcAuditFilter.cs  他的 一部分代碼在這里。通過這兒,可以看出這里的Filter把  filterContext.Result 進行改動。我們也可以在這里加上一層。

這里是Audit 的部分,原理類似。

            if (_auditingConfiguration.SaveReturnValues && filterContext.Result != null)
            {
                switch (filterContext.Result)
                {
                    case AbpJsonResult abpJsonResult:
                        if (abpJsonResult.Data is AjaxResponse ajaxResponse)
                        {
                            auditData.AuditInfo.ReturnValue = _auditSerializer.Serialize(ajaxResponse.Result);
                        }
                        else
                        {
                            auditData.AuditInfo.ReturnValue = _auditSerializer.Serialize(abpJsonResult.Data);
                        }
                        break;

                    case JsonResult jsonResult:
                        auditData.AuditInfo.ReturnValue = _auditSerializer.Serialize(jsonResult.Data);
                        break;

                    case ContentResult contentResult:
                        auditData.AuditInfo.ReturnValue = contentResult.Content;
                        break;

                }
            }

 在  .Netcore api 中生成的 swagger 文檔中,前端Angular 在攔截器中添加如下 處理

return next.handle(req1).pipe(tap(() => { },
            (err: any) => {
                if (err instanceof HttpErrorResponse) {
                    if (err.status !== 401) {
                        console.error(err.message);
                        return;
                    }
                    this.router.navigate(['login']);
                }
            }));

  handle(req),執行的就是請求后端。 這里的返回是一個Observable 對象。可以pipe或者 subscribe().

pipe里可以有一些 operator.  也就是一些方法。 scan()是一個累加器,會接受一個一個的值,然后把這些值一個一個的算出一個結果來,也就是會記住歷史,累計歷史。

他的初始值是一個參數:seed.

https://stackblitz.com/edit/dcm2d1?file=index.ts

下面的代碼,說明了merge和contact的差別

import { merge, interval, concat } from 'rxjs';
import { take, tap } from 'rxjs/operators';

const timer1 = interval(1000).pipe(tap(t=>console.log('timer1')),take(3));
const timer2 = interval(2000).pipe(tap(t=>console.log('timer2')));
const timer3 = interval(500).pipe(tap(t=>console.log('timer3')));
const concurrent = 2; // the argument
const merged = merge(timer1, timer2, timer3); // 可以替換為 contact 看看
merged.subscribe(x => console.log(x));

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM