ASP.NET MVC 的統一異常處理有多難?(衍生的意圖,出錯後如何保持表單的狀態?)

來源:互聯網
上載者:User

一個比較順手的開發架構,我們都希望開發人員不要去太關心異常的處理,除了一個特定異常需要特定處理外,我們都希望我們很多普通的異常都能由架構來幫我們搞定。比如異常的日誌記錄,異常資訊的提示,異常的進一步分類的判斷等等,我們都不希望開發人員去使用相同或類似的代碼去完成。簡單來講,我們不希望我們的代碼中出現太多的try…catch 代碼。如果在一個項目中,頻繁出現try…catch的代碼塊,一方面代碼不太優雅,另一方面也會給我們的代碼編碼帶來一定的障礙,由於變數範圍(try和catch屬於不同的代碼塊)的問題,我們很多時候不得不把變數定義在try…catch之外的代碼塊當中。因此,在很多商務邏輯的代碼中,我們一般都不太會去專門做異常的處理,而相反,我們經常會根據商務邏輯的需要拋出很多商務邏輯異常出來,拋給UI或是業務調用者,而這種異常很多時候是希望顯示給終端使用者的友好資訊提示。

因此,將異常的捕獲,處理和顯示放在UI代碼中,無論從哪個角度來看都是最好的選擇。結合ASP.NET MVC架構,為我們提供了的統一異常處理方案是重寫Controller.OnException方法,或者是實現IExceptionFilter介面的ActionFilter。然而,這樣真的就可以滿足我們統一異常處理的需要嗎?來看看下面的幾種情況:

1.

public ActionResult Index(){    var model = GetModel();    return View(model);}

在這種情況下,假設在GetModel的時候出現了異常,這時我們別無他法,即時你把異常捕獲處理了,返回到Index View任何無法顯示任何有用的資訊。此時,我們重新導向到統一友好錯誤頁面是可以接受的。因此,在這種情況下,MVC提供的異常處理機制來統一處理這種情況下的異常就會非常簡單有效。

2.

[HttpPost]public ActionResult Edit(User model){    if (ModelState.IsValid)    {        SaveModel(model); return RedirectToAction("Index", "Home")    }       return View(model);}

在這種情況下,假設我們在SaveModel時出現了異常,這個異常假設不是系統性異常,而是一個業務性異常。我們更希望是的,在使用者當前操作頁面上提示該異常資訊,保持使用者輸入值不變,使用者只需要根據提示訊息,修改一兩個輸入值即可再次提交表單,而不是重新導向到錯誤提示頁面之後再返回回來完全重新輸入表單。在這種要求下,MVC提供的異常處理機制就無法滿足需要,因為model這種異常在統一的異常處理上下文中無法得到。因此,我們就只能添加異常處理代碼塊了:

[HttpPost]public ActionResult Edit(User model){    try    {        if (ModelState.IsValid)        {            SaveModel(model);    return RedirectToAction("Index", "Home")        }    }    catch (Exception e)    {        //log        ModelState.AddModelError("", e.Message);    }    return View(model);}

而這樣的代碼,正是我們所希望避免的,然而這樣的性質的Action在我們的系統中比比皆是。不過,此時在滿足某種前提條件的情況下,假設我們的Model變數名都是”model”,我們是有可能通過ActionExecutingContext.ActionParameters得到我們所要的model值,提供給View。通過這種workaround的處理,我們也許可以很好的繞過此問題。我們再來看另一種情況:

3.

[HttpPost]public ActionResult Edit(User user){    if (ModelState.IsValid)    {        SaveModel(user);    }    var model = GetModel(user.Name);    ViewData["Title"] = "Edit";    return View(model);}

在這種情況下,也許我們除了try…catch外,真的沒有其它更好的辦法了。

異常處理一直都是我們軟體開發過程當中,不得不去面對的麻煩。我們程式員都很害怕,因為一個個不可預期的異常而導致我們的業務模組無法正確運行,無法友好的提示給使用者而招來抱怨,但是我們又不喜歡因為這些可能並不經常發生的意外而多做很多零碎事情,而且會讓代碼變得很醜。在一般的業務系統當中,我們更加不會加很多的catch並列句,去分門別類的處理各種各樣的異常。如何更加簡單,省事的把異常納入可控的範圍一直是我們努力的方向。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.