.net自定義錯誤頁面實現升級篇

来源:https://www.cnblogs.com/xiaoXuZhi/archive/2018/05/15/customErrors_httpErrorsUp.html
-Advertisement-
Play Games

在實際的web開發中,經常會遇到以下情況,導致給用不好的體驗:     a、程式未處理的異常,直接輸出顯示到用戶頁面     b、用戶訪問的資源不存在,直接顯示系統預設的404頁面     c、其它以下請求錯誤狀態的系統預設頁面(403等)   為了給用戶友好的體驗,在實際項目開發中, 需要對系統會... ...


  問題描述:

  在上一篇博文 “.net自定義錯誤頁面實現” 中已經介紹了在.net中如何實現自定義錯誤頁面實現(有需要者可以去上一篇博文瞭解),單純按照上一篇博文那樣設置,能夠實現所有請求的異常自定義跳轉,但是這樣又會產生一個問題:當通過ajax提交請求獲取介面提交請求,如果出現未處理的異常也會被重定向到自定義錯誤頁面。

  針對ajax請求或者介面請求,這樣返回一個重定向頁面,用戶體驗顯然不是太友好,針對這個問題,下麵簡單總結一下我自己的想法和解決方案,當然不一定科學和合理,所以也希望有大牛多多指點。

  解決思路,我想到的有二:
解決方案一:
  從物理結構上分割,將web項目嚴格分割成兩個項目(當然可根據需要繼續細分):網站(只有網站頁面資源等內容)、介面(包括網站的所有數據邏輯處理,頁面的數據請求交互都是直接同介面交互(js技術)),
  只是網站項目按照上一篇博文方式設置自定義錯誤頁面方式,這樣是能夠解決問題,項目也會更加的清晰,也有很多公司的項目就是按照這種方式(尤其是webApp),
  但是在實際項目中,很多項目是沒有達到這種嚴格區分的,所以下麵的解決方案二,將介紹一個更通用的方式

解決方法二:

  解決思路是:將上一篇博文 .net自定義錯誤頁面實現 與 上上一篇博文 .net捕捉全局未處理異常的3種方式 結合使用,併在實際開發中嚴格約定(出了url地址請求以外的其他請求都通過post請求實現交互),在撲捉到異常時,如果是post請求,處理異常,並清除異常。具體以步驟如下:
  第一步:定義一個請求處理結果數據MODEL,代碼如下:
  

    /// <summary>
    /// 請求結果MRequestResult
    /// </summary>
    public class MRequestResult
    {
        /// <summary>
        /// 請求結果編碼(是一個枚舉值)
        /// </summary>
        private RequestResultCodeEnum requestResultCode;

        /// <summary>
        /// 處理結果具體的返回值
        /// </summary>
        private object resultValue;

        /// <summary>
        /// 請求結果編碼(是一個枚舉值)
        /// </summary>
        public RequestResultCodeEnum RequestResultCode
        {
            get
            {
                return this.requestResultCode;
            }

            set
            {
                this.requestResultCode = value;
            }
        }

        /// <summary>
        /// 處理結果具體的返回值
        /// </summary>
        public object ResultValue
        {
            get
            {
                return this.resultValue;
            }

            set
            {
                this.resultValue = value;
            }
        }
    }


    /// <summary>
    /// 請求結果編碼枚舉值()
    /// </summary>
    public enum RequestResultCodeEnum
    {
        /// <summary>
        ///  請求成功
        /// </summary>
        Success = 1,

        /// <summary>
        /// 請求失敗
        /// </summary>
        Fail = -1,
    }

 

 

第二步:按照 上一篇博文: .net自定義錯誤頁面實現的步驟,配置好自定義錯誤頁面相關配置操作

第三步:按照 上上一篇博文:.net捕捉全局未處理異常的3種方式 的步驟實現全局異常為處理相關操作設置

第四步:在撲捉全局未處理的異常中,添加上針對post請求的異常處理過濾(直接輸入封裝後的),具體代碼如下:

  /// <summary>
        /// 異常處理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void context_Error(object sender, EventArgs e)
        {
            //此處處理異常
            HttpContext ctx = HttpContext.Current;
            HttpResponse response = ctx.Response;
            HttpRequest request = ctx.Request;

            //獲取到HttpUnhandledException異常,這個異常包含一個實際出現的異常
            Exception ex = ctx.Server.GetLastError();
            //實際發生的異常
            Exception iex = ex.InnerException;

            //// 異常日誌落地
            //// 異常日誌落地包括:記錄異常文本文件日誌、或者記錄異常日誌資料庫等等(根據實際項目需要做記錄)

            //// 獲取請求方法
            string httpMethod = request.HttpMethod;
            //// 如果是POST請求,那麼是以下請求之一
            //// ajax介面請求
            //// form表單提交
            //// 這種情況的異常,不用跳轉至自已的異常錯誤頁面,直接返回對應系統異常
            if (httpMethod.ToUpper() == "POST")
            {
                //// 構建返回對象值
                MRequestResult requestResultM = new MRequestResult();
                requestResultM.RequestResultCode = RequestResultCodeEnum.Fail;
                requestResultM.ResultValue = "系統異常,請聯繫管理員!";

                response.Write(JsonConvert.SerializeObject(requestResultM, Formatting.Indented));
                ctx.Server.ClearError();//處理完及時清理異常
            }
        }

 

代碼實例:

ajax請求方法及其邏輯處理實例代碼:

    $(function () {
        $.ajax({
            async: true,
            type: "post",
            url: "../ActionTestResult/ContentResultTest",
            data: "name=xu",
            success: function (resultValue) {

                if (resultValue) {
                    //// 解析處理結果
                    var resultObj = $.parseJSON(resultValue);

                    //// 當RequestResultCode==1 說明該請求成功
                    ////(備註:並不代表處理成功,具體是否處理成功需要通過ResultValue的值根據介面約定解析做相應的邏輯處理)
                    if (resultObj["RequestResultCode"] == 1) {
                        //// 自定義請求成功邏輯處理
                        //// 通過解析具體的ResultValue的值做相應的邏輯處理.....
                        if (resultObj["ResultValue"]) {
                            var doResult = resultObj["ResultValue"].split('^');
                            if (doResult && doResult.length > 1) {
                                if (doResult[0] == 1) {
                                    //// 說明處理成功,做相應的邏輯處理
                                    alert("處理成功!");
                                } else {
                                    //// 處理失敗
                                    alert(doResult[1]);
                                }

                            } else {
                                alert("操作失敗!");
                            }

                        } else {
                            alert("未知結果");
                        }

                    } else {
                        //// 說明請求異常
                        //// 自定義邏輯處理
                        alert(resultObj["ResultValue"]);
                    }
                } else {
                    //// 自定義邏輯處理
                    alert("操作失敗!");
                }

                console.log(resultValue);
            },
            error: function (data) {
                //// 自定義邏輯處理
                alert("系統異常,請聯繫管理員。電話:8888888");
                console.log(data);
            }
        });
    });

ajax對應的後臺請求接受實例代碼:

        /// <summary>
        /// 測試
        /// </summary>
        /// <returns></returns>
        public ContentResult ContentResultTest(string name)
        {
            //// 構建請求處理結果Model
            MRequestResult requestResultM = new MRequestResult() { RequestResultCode = RequestResultCodeEnum.Success };

            //// 業務處理結果
            string doResult = string.Empty;

            //// 本次自作簡單的參數非空判斷,只一個示例
            //// 處理結果本例中也只是通過^鏈接表示,在實際處理過程中,可以將結果通過一個Json字元串
            if (string.IsNullOrEmpty(name))
            {
                doResult = "-1^操作失敗:名稱不能為空!";
            }
            else
            {
                ///// 其他自定義業務邏輯處理,此處省略.....
                doResult = "1^操作成功";
            }

            requestResultM.ResultValue = doResult;

            //// 返回結果
            return Content(JsonConvert.SerializeObject(requestResultM, Formatting.Indented));

        }

 

是不是覺得說的有點繞,本人表述能力有限,不懂的評論交流。
最後:個人能力有限也許該解決方式並不友好,有更好的解決方法,也歡迎留言交流,多多指點,多多指教


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • python重要模塊之subprocess模塊 我們經常要通過python去執行系統的命令或者腳本,系統的shell命令是獨立於你的python進程之外的,每執行一條命令,就相當於發起了一個新的進程,通過python調用系統命令或腳本的模塊。 之前我們也學到過和系統交互的模塊 os模塊 除了so.s ...
  • 類屬性 定義在類裡面,方法外面的屬性,一般屬於這個類,如下麵的 num 就是類屬性: 類屬性用 實例.類屬性 或者 類.類屬性 都可以訪問, 如 a = Test() 用 a.num 可以訪問 ,但是如果這個實例有一個實例屬性 self.num 那麼這樣訪問的其實是 self.num , 所以一般用 ...
  • 是不是很想知道那三步? 其實很簡單! 1、打開網頁,獲取源碼 2、獲取圖片 3、保存圖片地址與下載圖片 打開網頁,獲取源碼 *由於多人同時爬蟲某個網站時候,會造成數據冗餘,網站崩潰,所以一些網站是禁止爬蟲的,會返回403拒絕訪問的錯誤信息。 獲取不到想要的內容/請求失敗/IP容易被封……..等 *解 ...
  • 1.不包含包名 2.類名為:public class Main(){} 3.再就是輸入輸出格式符不符合題目要求了 ...
  • using WL.Infrastructure.Http; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text... ...
  • using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WL.Infrastructure.Commom... ...
  • 基於ASP.NET 4.0+MYSQL開發的微商城系統,輕量級三層架構,沒有使用太多新潮的架構和技術,即使是小白.NET新手,很可以很容易上手二次開發,使用完全免費 官方網站:http://www.qizhanbang.com ...
  • 持續集成交付部署是什麼意思,它給我們帶來什麼好處? 先貼一張圖 持續集成(Continuous Integration) 持續集成強調開發人員提交了新代碼之後,立刻進行構建、(單元)測試(這個要看情況了是否需要) 持續交付(Continuous Delivery) 持續交付在持續集成的基礎上,將集成 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...