ASP.NET MVC學習之模型模板篇


一.前言

如果你使用ASP.NET MVC制作后台一定會愛上它的EditorForModalDisplayForModalLabelForModal方法,因為這些方法可以將模型直接變成對應的標簽,省了不少事,但是對於一些苛刻的人來說,一定想自定義,下面我們會先介紹如何使用,然后介紹如何自定義。

 

二.正文

 

1.輸出模型

首先我們要新建一個Home控制器,對應的還要有一個Index動作,和Index視圖,接着我們在Modal下新建一個Address類:

 1 namespace MvcStudy.Models
 2 {
 3     public class Address
 4     {
 5         public string Line1 { get; set; }
 6         public string Line2 { get; set; }
 7         public string City { get; set; }
 8         public string PostalCode { get; set; }
 9         public string Country { get; set; }
10     }
11 }

 

接着再新建一個Role枚舉:

1 namespace MvcStudy.Models
2 {
3     public enum Role
4     {
5         Admin,
6         User,
7         Guest
8     }
9 }

 

最后新建一個Person類:

 1 namespace MvcStudy.Models
 2 {
 3     public partial class Person
 4     {
 5         public int PersonId { get; set; }
 6         public string FirstName { get; set; }
 7         public string LastName { get; set; }
 8         public DateTime BirthDate { get; set; }
 9         public Address HomeAddress { get; set; }
10         public bool IsApproved { get; set; }
11         public Role Role { get; set; }
12     }
13 }

 

然后我們在Home控制器的Index方法中寫入如下代碼:

 1 namespace MvcStudy.Controllers
 2 {
 3     public class HomeController : Controller
 4     {
 5         public ActionResult Index()
 6         {
 7             Person p = new Person
 8             {
 9                 PersonId = 1,
10                 HomeAddress = new Address
11                 {
12                     City = "zj",
13                     Country = "js",
14                     Line1 = "111",
15                     Line2 = "222",
16                     PostalCode = "asdsa"
17                 },
18                 Role = Models.Role.User,
19                 BirthDate = DateTime.Now,
20                 FirstName = "y",
21                 LastName = "zf",
22                 IsApproved = false
23             };
24             return View(p);
25         }
26     }
27 }

 

同時還要確保Index視圖的model的類型是Person類型,如果不是可以在最頂部加上如下代碼:

@model MvcStudy.Models.Person

 

接着我們打開Index視圖,在其中寫入@Html.EditorForModel(),運行之后我們可以看到頁面上輸出了該類的屬性:

圖 1.1

 

但是我們可以發現PersonId也輸出了而且還可以編輯,這可不是我們所想要的,所以我們要在模型的PersonId上加上HiddenInput注解屬性,重新編譯后我們可以看到PersonId已經不可編輯了:

 

但是有時我們根本不想讓它顯示出來,這個時候我們需要修改HiddenInput注解屬性,將DisplayValue設置為false即可,但是你可以通過查看頁面的html源代碼看到存在一個隱藏的input標簽,當然如果你根本不想讓這個屬性存在於頁面中我們可以將HiddenInput修改成[ScaffoldColumn(false)]即可。

 

通過圖1.1我們可以發現label中顯示的都是該屬性的名稱,並不符合實際的使用習慣,所以我們還要給這些屬性加上該顯示的名稱:

 1 namespace MvcStudy.Models
 2 {
 3     public partial class Person
 4     {
 5         [ScaffoldColumn(false)]
 6         public int PersonId { get; set; }
 7         [Display(Name = "")]
 8         public string FirstName { get; set; }
 9         [Display(Name = "")]
10         public string LastName { get; set; }
11         [Display(Name = "生日")]
12         public DateTime BirthDate { get; set; }
13         public Address HomeAddress { get; set; }
14         [Display(Name = "是否啟用")]
15         public bool IsApproved { get; set; }
16         [Display(Name = "角色")]
17         public Role Role { get; set; }
18     }
19 }

 

重新編譯之后我們可以看到頁面變成了如下所示:

 

我們可以看到字符串都使用input去呈現,但是有時候這樣並不符合實際情況,那么我們就要修改屬性的DataType類型,比如我們將姓修改成富文本,修改Person代碼:

 1 namespace MvcStudy.Models
 2 {
 3     public partial class Person
 4     {
 5         [ScaffoldColumn(false)]
 6         public int PersonId { get; set; }
 7         [Display(Name = "")]
 8         [DataType(DataType.Text)]
 9         public string FirstName { get; set; }
10         [Display(Name = "")]
11         [DataType(DataType.MultilineText)]
12         public string LastName { get; set; }
13         [Display(Name = "生日")]
14         [DataType(DataType.DateTime)]
15         public DateTime BirthDate { get; set; }
16         public Address HomeAddress { get; set; }
17         [Display(Name = "是否啟用")]
18         public bool IsApproved { get; set; }
19         [Display(Name = "角色")]
20         public Role Role { get; set; }
21     }
22 }

 然后我們重新編譯之后可以看到最終想要的效果了,當然這些都是ASP.NET MVC根據類型自動判斷的並選擇對應的模板,所以我們也可以直接設置屬性使用的模板,這樣我們可以通過使用UIHint去指定模板的名稱(其實就是視圖的名稱)。

 

 

2.將元數據用於分布類

現在開發網站模型都是工具自動生成了,如果按照我們上面的這種方法,一旦重新生成模型了,那么我們就需要重新將注解屬性加上上去,既費時又費力。幸好ASP.NET MVC提供了解決方案,我們只需要為那個模型類加上一個分布類即可,比如下面我們將Person的注解屬性全部轉移到分布類中:

 

筆者新建了一個名為PersonExt的類:

 1 namespace MvcStudy.Models
 2 {
 3     public class PersonDataBindSource
 4     {
 5         [ScaffoldColumn(false)]
 6         public int PersonId { get; set; }
 7         [Display(Name = "")]
 8         [DataType(DataType.Text)]
 9         public string FirstName { get; set; }
10         [Display(Name = "")]
11         [DataType(DataType.MultilineText)]
12         public string LastName { get; set; }
13         [Display(Name = "生日")]
14         [DataType(DataType.DateTime)]
15         public DateTime BirthDate { get; set; }
16         public Address HomeAddress { get; set; }
17         [Display(Name = "是否啟用")]
18         public bool IsApproved { get; set; }
19         [Display(Name = "角色")]
20         public Role Role { get; set; }
21     }
22 
23     [MetadataType(typeof(PersonDataBindSource))]
24     public partial class Person
25     {
26     }
27 }

然后我們就可以刪除Person類的注解屬性了,重新編譯可以看到最后的輸出還是一樣的。細心的讀者會發現Address屬性並沒有輸出,這是因為輔助器並不會遞歸查找,所以我們需要在Index視圖中寫入@Html.EditorFor(x => x.HomeAddress)即可。

 

 

3.使用自定義模板

通過上面的例子我們發現Role呈現出來的是輸入框,但實際上應該是選擇的,這個時候我們就需要自定義模板,首先我們在Views/Shared下新建一個EditorTemplates文件夾,然后新建一個Role視圖,強類型為Role類型,並且不使用母版。然后在視圖中寫入如下代碼:

1 <select id="Role" name="Role">
2     @foreach (Role value in Enum.GetValues(typeof(Role)))
3     {
4         <option value="@value" @(Model == value ?"selected='selected'":"")>@value</option>
5     }
6 </select>

 

接着刷新頁面,我們就可以看到Role變成了下拉選擇了:

當然文件夾的名稱是一種規范,如果需要自定了Display模板,則新建DisplayTemplates文件夾,然后根據類型新建對應名稱的視圖,當然我們也可以新建一些ASP.NET MVC已經提供了模板的類型,而ASP.NET MVC會首先使用我們的模板而不是自帶的。當然我們也可以通過UIHint指定模板。有時候我們需要設置標簽的Id,那么我們可以通過ViewData.TemplateInfo.GetFullHtmlFieldId方法獲取IdViewData.TemplateInfo.GetFullHtmlFieldName用來獲取name,如果你對這些還不夠滿意,那么你可以通過ViewData.ModelMetadata中的屬性獲取模型中屬性的全部信息。

 

 

4.傳遞參數到模板中

有時候我們需要在模型模板與模板之間傳遞自定義的參數,那么下面的方式將可以實現。首先我們在PersonExt文件中給BirthDate屬性加上如下的注解屬性:

1 [AdditionalMetadata("val","test")]

 

 

該注解屬性的第一個參數是Key,第二個是對應的參數,然后我們在Views/Shared/EditorTemplates中新建一個DateTime視圖,並在其中寫入如下代碼:

 1 @model DateTime
 2 
 3 @{
 4     Layout = null;
 5 }
 6 
 7 @Html.TextBox(ViewData.TemplateInfo.GetFullHtmlFieldName("a"), Model)
 8 @if(ViewData.ModelMetadata.AdditionalValues.ContainsKey("val"))
 9 {
10     @Html.Label(ViewData.ModelMetadata.AdditionalValues["val"].ToString())
11 }

 

這里ModelMetadataAdditionalValues屬性保存了傳遞的自定義參數,上面我們首先判斷是否存在Keyval的參數,然后在將val的值顯示出來,重新編譯之后刷新頁面我們可以看到如下的效果:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM