1. 程式人生 > >基於ASP.NET MVC 3的企業應用專案總結

基於ASP.NET MVC 3的企業應用專案總結

為期三個月的開發加測試工作終於告一段落了,這是我們團隊第一次採用ASP.NET MVC(直接使用最新的MVC 3)開發企業應用,期間碰到了很多問題,但在大家的努力下,也都一一解決,先簡單介紹一下專案情況吧,是公司的一套業務運營系統,總的從技術實現難度來講,沒有什麼特殊的地方,只有相關部分的業務邏輯演算法比較複雜。專案開始前,最大的風險在於整個team除了另外一名同事和我使用過MVC,其他人都是第一次使用,並且另外那名同事在專案開始一個月左右離職了~~!好在通過大量的交流溝通、code review、內測等手段下,專案基本成功完成。

一、技術架構介紹

  基於.Net的多層解決方案,web框架採用了微軟的ASP.NET MVC 3(檢視引擎為Razor),資料層採用Entity Framework 4.0。介面元件方面使用了Telerik for MVC版本,JS框架依然是強大的JQuery。 系統提供了中、英兩套語言版本,採用微軟官方推薦的多語言解決方案,該方案很容易擴充套件其他語言版本。

二、MVC

  個人感覺ASP.NET MVC 3相比2和1,並沒有帶來革命性的變化,但一些小的改進還是相當不錯的,也提高了不少開發人員的效率。
以下列表顯示了我們用到的一些ASP.NET MVC的特性(包括ASP.NET MVC 3但不限於3)
1. 基於layout的頁面結構,一個首頁可以拆分成如下: 包含title、head、body、以及公用JS、CSS檔案的最頂層layout。 包含選單導航的分部檢視(Partial View) 包含主頁面內容的View。 主頁面裡又可以包含其他公共的分部檢視,或為了層次更清晰而人為拆分的邏輯部分檢視(設計合理的部分檢視有利於提高程式碼層次的清晰程度,但過多的使用也會降低系統性能,畢竟多了一些IO操作)。 
2. 通過使用ViewResult、ActionResult、PartialResult、JsonResult輸出不同的內容。 
3. 新增了Dynamic特性,配合Razor可以很方便的在檢視上使用控制器提供的資料。 
4. MVC Chart元件可以很方便的輸出比較專業的圖表。 
5. 控制器基類提供了很多重寫方法,可以較為方便的進行一些全域性的處理,例如:異常、方法級別的注入等。 
6. unobtrusive js,通過伺服器端ModelMetadata和客戶端的unobtrusive js,可以做到前後臺的統一驗證,大大減少開發量。

三、Razor

  採用了微軟最新的Razor(模板引擎語言)配合MVC3進行開發,新一代的檢視引擎Razor以簡潔的“@”開頭的寫法,對強型別的智慧感知做的也非常不錯(不過在JavaScript程式碼部分的智慧感知還是有些問題)。 相比ASPX檢視引擎,Razor還是勝在簡潔上,也有第三方的NVelocity模板引擎,雖然語法也很簡潔,但智慧感知方面就做的比較差了,因此,開發ASP.NET MVC 3,Razor還是首選。 至於效能上的比較,沒有實際分析過,可能會比ASPX略遜一些。
總結Razor的優點如下: 
1. 程式碼流暢簡潔。 
2. 與HTML結合很順暢,不需要單獨處理大括號。
3. 程式碼高亮顯示。 
4. 很方便的輸出單行文字(@:)或多行文字()。

四、Entity Framework

  資料層採用微軟提供的ORM框架Entity Framework,並配合Linq To Entity,能夠以簡潔的linq語句或lambda表示式,來代替複雜冗長的SQL語句。 總體上來講EF相比Linq To SQL,並沒有特別大的不同,其中結合Validation類來對Model進行MetadataType的標記,來實現資料的校驗,感覺是一個比較不錯的方式。更能體現程式碼單一職責原則,我們不必要在控制器裡寫大量的校驗邏輯。
  EF的edmx檔案在從資料庫更新的時候,容易出現更新不成功的情況,這時候則需要將實體刪除並從資料庫新增就可以解決這個問題。 對於EF的DBContext,在不同層傳遞的時候,應該儘量一致,個人更傾向於例項化物件的方式,而且比較好的實踐方式是: 在業務層持有一個全域性的資料層物件引用,在控制器裡使用例項化的業務層物件對資料庫進行讀寫操作。 在專案的前期,因為大量使用了資料層或業務層的靜態方法,以至於在業務邏輯相對簡單的系統管理模組出現了大量的bug,主要的原因就是資料上下文使用混亂,前後不一致,應該說是我們的一個教訓。 需要謹慎處理延遲載入,以降低效能方面的影響。什麼時候需要延遲載入、什麼時候不需要延遲載入,感覺還是跟具體的業務邏輯有關,不能一概而論。 資料物件的使用也是要考慮的一方面,尤其是在前臺更改了某些資料屬性之後,在同一個上下文裡進行資料儲存操作後,可能會出現你所不期望的修改。尤其是在複雜的業務計算類庫上面,一個物件經過重重傳遞,很容易出這個問題,並且不太好查。

總結:要明確的知道資料物件的使用範圍。

五、AOP

  對於ASP.NET MVC 3來講,天生就是支援AOP的,框架自帶的ActionFilterAttribute基類提供了四個過載方法,
如下所示: 
1. public virtual void OnActionExecuted(ActionExecutedContext filterContext)該方法在Action執行之後觸發。
2. public virtual void OnActionExecuting(ActionExecutingContext filterContext)該方法在Action執行之前觸發。 
3. public virtual void OnResultExecuted(ResultExecutedContext filterContext)該方法在Result渲染完之後觸發。
4. public virtual void OnResultExecuting(ResultExecutingContext filterContext)該方法在Result渲染之前觸發。

通過這四個過載方法,可以非常方便的將程式碼邏輯織入到Action的生命週期內。 對於我們這個系統,實現瞭如下幾個方面的織入: 
1. 功能許可權控制。
2. 資料許可權控制。 
3. 專案狀態檢查。 
4. 操作日誌。

AOP帶來的好處也是顯而易見的,減少程式碼量、降低業務邏輯和非業務邏輯程式碼的耦合度、便於維護。

六、Telerik

  為了提高開發效率和複用程式碼,在介面上也大量的使用了Telerik控制元件for ASP.NET MVC版本。
主要有如下應用:
DatePicker,日期選擇元件,其中可以設定可以選取的範圍是亮點,但其本身繫結的一些事件也是有利有弊(例如Onblur之後的自動設定日期值),客戶端不能靈活的控制。
Window,仿模態視窗,彈窗利器。
Grid,表格元件,功能很強大,但有些特殊場景還是很彆扭。同樣是客戶端控制程度不夠。
TreeView,樹元件,功能也很強大,很好用。

總結:有一套好的可複用元件確實能大大提高開發效率,但前提是要對其有較好的把控能力,否則容易適得其反。

七、多語言解決方案

  採用微軟官方推薦的資原始檔做法,我們這個系統有中、英文兩個版本,則在所有的顯示欄位、互動提示等地方,全部使用了資原始檔標籤。 其原理就是根據使用者選擇的語言種類(存到cookie),動態設定當前執行緒的語言環境,剩下的事情微軟已經幫我們做好了,實現起來很簡單,推薦使用。

關鍵程式碼:

?
HttpCookie hk = Utils.Language.GetLangCookie(); string langName = ""; if (hk != null) { langName = hk.Value; } else { langName = "zh-cn"; } CultureInfo cultureInfo = new System.Globalization.CultureInfo(langName);<br>System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo; <br>System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);

八、其他:log4net、NPOI

  同時也採用了一些其他優秀的開源框架: 使用log4net來記錄異常日誌和一些操作日誌,使用npoi來進行excel操作。這兩個框架都是從JAVA平臺移植過來,不得不說,JAVA社群在開源框架方面的研究要勝於.Net。

九、未來考慮

  引入Ioc框架:為了降低業務層與資料層、控制器之間的耦合,使程式碼更靈活以及更容易擴充套件和維護,考慮後續引入IOC框架(例如:unity、spring.net、castle windsor等)
  採用獨立快取伺服器:一直以來,快取都是提升系統性能最廉價的解決方案,目前我們需要快取的資料量較小,直接使用.Net自帶快取進行快取處理,例如:組織機構、功能選單等,雖然.NET自帶的快取功能很強大,但畢竟和app server共用記憶體,且處於同一應用程式域內,如果在快取使用較多的情況下,效能不是很理想。未來考慮使用分散式快取,例如:memcache、redis等優秀的第三方快取框架。
  更好的使用者體驗,主要體現在優化部分操作流程和頁面操作體驗。
  WCF重構部分服務以支撐更多不同型別的客戶端