.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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...