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的值显示出来,重新编译之后刷新页面我们可以看到如下的效果:

至此基本的模型模板结束了。

时间: 2024-10-12 04:36:26

ASP.NET MVC学习之模型模板篇的相关文章

ASP.NET MVC学习之模型验证篇

一.学习前的一句话 在这里要先感谢那些能够点开我随笔的博友们.慢慢的已经在博客园中度过一年半了,伊始只是将博客园作为自己学习的记录本一样使用,也不敢将自己的随笔发表到博客园首页,生怕自己的技艺不高,反倒成了笑话.但是随着时间的推移,再也按捺不住这种想法,于是就写了一篇随笔发表到博客园首页.让我意想不到的是有许多人都看了,而且也留下了评论.这让我鼓起勇气写了第二.三.四篇.到现在的连载,这里我希望那些从未发表过随笔的人可以尝试去发表,在这里他人不会嘲讽你,而是会给你更好的建议.说了这么多下面我们继

ASP.NET MVC学习之模型绑定(1)

一.前言 下面我们将开始学习模型绑定,通过下面的知识我们将能够理解ASP.NET MVC模型的模型绑定器是如何将http请求中的数据转换成模型的,其中我们重点讲述的是表单数据. 二.正文 1.简单类型绑定 学过一定ASP.NET MVC都会为这个特点所骄傲,就是能够将表单中与同名的参数映射,这相比操作ASP.NET控件来获取值轻便了许多,但是正如上面所说的那样要同名(大小写不区分),下面我们会讲述如何自己去指定. 首先我们在HomeController(如果不存在则创建)中获取表单中的值并显示:

ASP.NET MVC —— Model之一模型模板

http://www.cnblogs.com/lzhp/archive/2013/03/25/2981650.html Mvc model系列文章主要分为三部分:Model Templates,Model Binding,Model Validation.本篇文章主要内容包括下面三个部分: A.使用模板视图助手 B.自定义视图模板系统 C.理解元数据提供体系 一.使用模板视图助手 1.1助手体验 模板视图助手,我理解为MVC提供的根据model中定义的数据类型,来生成视图(View)标签的助手.

ASP.NET MVC学习之模型绑定(2)

3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了很多过程中的控制,所以我们就需要使用手工的方式进行绑定.下面我们通过一个例子来说明,首先打开Views/Home/Index.cshtml页面,并输入如下代码: 1 @{ 2 ViewBag.Title = "Index"; 3 } 4 5 @if (TempData.ContainsKey("msg")) 6 { 7 <h1> 8 @TempDa

ASP.NET MVC学习之Ajax(完结)

一.前言 通过上面的一番学习,大家一定收获不少.但是总归会有一个结束的时候,但是这个结束也意味着新的开始. 如果你是从事ASP.NET开发,并且也使用了第三方控件,那么一定会觉得ASP.NET开发ajax十分的简单,而ASP.NET MVC学习到现在页面都是刷新的,所以这节就是ASP.NET MVC的最后一节,通过这节的学习我们将能够实现通过ajax提交表单,下面我们开始继续学习. 二.准备工作 1.首先确保引用了以下js库在_Layout中: 2.新建一个HomeController,然后在其

ASP.NET MVC学习之路由篇(1)

原文:ASP.NET MVC学习之路由篇(1) 一.前言 作为一个从ASP.NET转入到ASP.NET MVC的开发人员而言,可能在开发ASP.NET网站的时候就已经开始在使用路由了. 只不过在ASP.NET MVC中路由是关键部分,而在ASP.NET中需要自行加进去.下面我们将学习ASP.NET MVC中的路由 系统. 二.准备工作 1.新建一个ASP.NET MVC4项目 2.模板选择空 3.在Controllers中添加一个Home控制器 4.打开App_Start中的RouteConfi

ASP.NET MVC学习之控制器篇

一.前言 许久之后终于可以继续我的ASP.NET MVC连载了,之前我们全面的讲述了路由相关的知识,下面我们将开始控制器和动作的讲解. ASP.NET MVC学习之路由篇幅(1) ASP.NET MVC学习之路由篇幅(2) ASP.NET MVC学习之路由篇幅(3) 二.正文 1.IController的使用 这个接口可能很多人都没有使用过,但是我们常用的Controller类实现了这个接口,而且只要实现这个接口就可以作为一个控制器,当然很多的内部的处理就要我们自己去做了. 下面我利用ICont

ASP.NET MVC学习之过滤器篇(2)

下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习. 3.动作过滤器 顾名思义,这个过滤器就是在动作方法调用前与调用后响应的.我们可以在调用前更改实际调用的动作,也可以在动作调用完成之后更改最终返回的结果,当然很多人一定不太明白这个到底可以干什么, 下面我们举一个比较实际的例子: 相信理解过网站的安全的一定知道跨站请求(CSRF具体可以自行百度,这里我就不去解释了),当然也有解决方案,那就是给页面中增加一个识别码,当页面进行POST请求时,首先判断识别码是否正确, 如果正确则继

ASP.NET MVC学习之视图篇(2)

继ASP.NET MVC学习之视图(1)学习 4.HTML辅助器 虽然在ASP.NET MVC中我们已经摆脱了ASP.NET的控件,但是对于页面中需要循环标签的情况依然还是存在,可能很多人认为用foreach就可以完成,但是这个仅仅只是针对单个循环,如果多个循环中都要使用到同样的标签呢?下面笔者就介绍两种方式让我们事半功倍. 首先是针对单个页面的内联辅助器,如果我们遇到只要在单个页面中不断使用的标签的时候,这个方式非常的轻便,比如下面的代码根据文本内容和样式类生成li标签的辅助器(Views/H