官方教程已經翻譯完了,在此基礎上,再做一些拓展,目標是做本土化調整,適合國內項目開發的現狀,比如,對英語國家來說,庫表字段名、模型屬性名、頁面顯示名都可以一樣,完全沒必要區分出來,而對於國內來說,顯示的列表頁面列標題欄或是詳細頁面的字段說明是中文的,庫表里存儲的字段和模型屬性是英文。目前沒有明確的規划,想到哪寫到哪,來源也雜,有查閱英文資料,有參閱前人寫過的文章,還有自己摸索的,先寫,最終再整理排序。
本文我們就來解決一下上文提到的如何為模型屬性增加中文顯示名稱的問題。在官方教程的例子中,你會發現MVC已經做了漢化,但是漢化並不完全,比如很多自動生成的按鈕和鏈接,都是英文的。在列表頁面,列標題欄是英文名稱,詳細頁面的字段說明,也是英文的,很明顯,不能將這樣的展示作為最終效果交付。
首先我們來看一下官方教程中生成的Movie的Index視圖,打開Views/Movie/Index.cshtml文件,腳手架自動生成的列表頁面表格的表頭如下所示:
<tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Genra) </th> <th> @Html.DisplayNameFor(model => model.Price) </th> <th> @Html.DisplayNameFor(model => model.Rating) </th> <th> @Html.DisplayNameFor(model => model.Date) </th> <th></th> </tr>
要進行漢化,最笨的辦法是直接修改視圖,例如將@Html.DisplayNameFor(model => model.Name)修改為“影片名稱”。這樣做可以實現漢化效果,但是非常繁瑣,耗時耗力且易出錯。列比較多的情況下,容易發生列對應錯位問題。若要修改屬性的中文顯示名稱,同樣需要在CRUD多個視圖進行手工調整,工作量顯而易見是很大的。而且,也違背前面所提到的“干爽”(DRY)原則。
由前面教程中為模型增加驗證屬性,我們可以得到啟發,是不是可以僅在模型類中定義中文顯示名稱一次,而在各個視圖中自動應用呢?事實上,MVC已經做了該方面的處理工作。由上面代碼可以知道,腳手架機制並沒有在視圖代碼中寫死,直接在列標題中寫Name/Genra等,而是調用了Html助手類的DisplayNameFor方法,傳入模型屬性,獲取顯示名稱。你僅需要在模型類中為屬性增加中文顯示名稱屬性即可。具體做法是,打開Models/Movies.cs,增加Display屬性,代碼如下所示:
public class Movie { public int ID { get; set; } [Display(Name="片名")] public string Name { get; set; } [Display(Name = "風格")] public string Genra { get; set; } [Display(Name = "價格")] public decimal Price { get; set; } [Display(Name = "上映日期")] public DateTime Date { get; set; } [Display(Name = "評價")] public string Rating { get; set; } }
即為模型屬性增加Display,設置參數Name值為要顯示的中文名稱。修改后執行生成項目操作,運行,可以看到,列表頁面以及增刪改頁面都自動生效了,顯示的是中文字段名稱。
查看Display屬性官方幫助如下:
命名空間: System.ComponentModel.DataAnnotations
DisplayAttribute 類:提供一個通用特性,使您可以為實體分部類的類型和成員指定可本地化的字符串。
上文我們使用的Name參數,其實遠遠不止這些,本想在下面挑幾個實用的來說一下,比如第一個AutoGenerateField,官方說明是獲取或設置一個值,該值指示是否應自動生成用戶界面以顯示此字段。
在實際業務開發中,往往有些字段是隱藏用於后台處理的,不需要也不應該顯示給用戶,於是嘗試性加了,如下
[Display(AutoGenerateField = false, Name = "風格")]
public string Genra { get; set; }
結果……發現無論如何,該參數無法生效……設置參數AutoGenerateField 為false的Genra ,編譯和運行都未報錯或者警告,但是運行結果是,始終會在視圖中自動生成……既查了官方說明,也根據關鍵字搜了網上結果,沒找到一個合理的解釋。又嘗試了一下下面的Description參數,同樣沒有效果。於是,推測,System.ComponentModel.DataAnnotations命名空間下的除了Name以外的這幾個參數,僅在WinForm下有效,而在ASP.NET MVC下,無效……望有知情人士告知我的推測是否正確或者真正的原因是什么或者我的用法哪里有誤,多謝:)