当前位置: 首页 > news >正文

Asp.Net MVC4 系列--进阶篇之Helper(2)

本章接着介绍Asp.NetMVC4中的Helper

 

首先做准备工作,为了读者方便阅读,笔者把上篇文章中(Asp.Net MVC4系列—进阶篇之Helper(1)) 的代码再复制在这边一份,这篇文章都以此为开始:

Person类(Model中):


  public class Person
    {
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
        public Address HomeAddress { get; set; }
        public bool IsApproved { get; set; }
        public Role Role { get; set; }
    }


    public class Address
    {
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string City { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
    }
    public  enum Role
    {
        Admin,
        User,
        Guest
}


PersonController.cs

 

   public class PersonController : Controller
   {
        public ActionResult CreatePerson()
        {
            return View(new Person());
        }
 
        [HttpPost]
        public ActionResult CreatePerson(Person person)
        {
            return View(person);
        }
   }


 

Route:

      

     routes.MapRoute(
name: "FormRoute",
url:"app/forms/{controller}/{action}"
);
        }

View(CreatePerson.cshtml)


<html>
@modelMVCHelperStudy.Models.Person
@{
   ViewBag.Title = "CreatePerson";
 
}
<h2>CreatePerson</h2>
<body>
 
   @using(Html.BeginRouteForm("FormRoute", new {},FormMethod.Post,
new { @class ="personClass", data_formType="person"})) {
<div  class="dataElem">
<label>PersonId</label>
@Html.TextBoxFor(m =>m.PersonId)
</div>
<div class="dataElem">
<label>FirstName</label>
@Html.TextBoxFor(m => m.FirstName)
</div>
<div class="dataElem">
<label>LastName</label>
@Html.TextBoxFor(m =>m.LastName)
</div>
<div class="dataElem">
<label>Role</label>
@Html.DropDownListFor(m =>m.Role,
new SelectList(Enum.GetNames(typeof(MVCHelperStudy.Models.Role))))
</div>
<input type="submit" value="Submit" />
}
 
</body>
</html>


测试运行:


首先,使用模板方法重构View

把表单中间代码替换为:

<div class="dataElem">
<label>PersonId</label>
@Html.Editor("PersonId")
</div>
<div class="dataElem">
<label>FirstName</label>
@Html.Editor("FirstName")
</div>
<div class="dataElem">
<label>LastName</label>
@Html.EditorFor(m =>m.LastName)
</div>
<div class="dataElem">
<label>Role</label>
@Html.EditorFor(m => m.Role)
</div>
<div class="dataElem">
<label>BirthDate</label>
@Html.EditorFor(m =>m.BirthDate)
</div>


 

代码说明:使用了Html.Editor替代以前的实现。

看一下生成的html

<form action="/app/forms/Person/CreatePerson" class="personClass" data-formType="person" method="post"><div class="dataElem">
<label>PersonId</label>
<input  class="text-box single-line" data-val="true" data-val-number="The field PersonId must be anumber." data-val-required="The PersonId field is required."  id="PersonId" name="PersonId" type="number"  value="0" />
</div>
<div  class="dataElem">
<label>FirstName</label>
<input  class="text-box single-line" id="FirstName" name="FirstName" type="text" value="" />
</div>
<div class="dataElem">
<label>LastName</label>
<input class="text-boxsingle-line" id="LastName" name="LastName" type="text" value="" />
</div>
<div class="dataElem">
<label>Role</label>
<input class="text-boxsingle-line" data-val="true" data-val-required="The Rolefield is required." id="Role" name="Role" type="text" value="Admin" />
</div>
<div class="dataElem">
<label>BirthDate</label>
<input class="text-boxsingle-line" data-val="true" data-val-date="The fieldBirthDate must be a date." data-val-required="The BirthDate field isrequired." id="BirthDate" name="BirthDate" type="datetime" value="1/1/0001 12:00:00 AM" />
</div>
<input  type="submit" value="Submit" />
</form>


对比之前生成的html,区别就是多了“type”属性,好处是它使得html5根据不同的type显示不同,这需要支持html5的浏览器来实现。

常用的MVC模板helper方法

Html.Display(“name”)

Html.DisplayFor(m=>m.name)

Html.Editor(“name”)

Html.EditorFor(m=>m.name)

Html.Label(“name”)

Html.LabelFor(m=>m.name)

 

Label 方法和Display方法

调整Controller代码:

  public ActionResult CreatePerson()
        {
           
  return View(newPerson()
                {
                   FirstName = "iori",
                   LastName = "l",
                   PersonId = 100,
                   BirthDate = DateTime.Now.AddYears(-20)
                });
        }


返回一个默认的Person。

 

调整View代码:

<div class="dataElem">
@Html.Label("PersonId")
@Html.Display("PersonId")
</div>
<div class="dataElem">
@Html.Label("FirstName")
@Html.Display("FirstName")
</div>
<div class="dataElem">
@Html.LabelFor(m => m.LastName)
@Html.DisplayFor(m => m.LastName)
</div>
<div class="dataElem">
@Html.LabelFor(m => m.Role)
@Html.DisplayFor(m => m.Role)
</div>
<div class="dataElem">
@Html.LabelFor(m => m.BirthDate)
@Html.DisplayFor(m => m.BirthDate)
</div>


 

为了对比Display和Label,因此分别显示。测试结果:


可以看到,Display是显示Property的Value,而Label是显示Property的Name

再对比一下生成的html:

<form action="/app/forms/Person/CreatePerson" class="personClass" data-formType="person" method="post">
<div class="dataElem">
<label for="PersonId">PersonId</label>
100
</div>
<div class="dataElem">
<label for="FirstName">FirstName</label>
iori
</div>
<div class="dataElem">
<label for="LastName">LastName</label>
l
</div>
<div class="dataElem">
<label for="Role">Role</label>
Admin
</div>
<div class="dataElem">
<label for="BirthDate">BirthDate</label>
13/4/1994 9:24:09 PM
</div>
<input type="submit"  value="Submit"/>
</form>


可以看到,label自动生成的for属性,而display则直接把值打在了页面上,甚至没有conver任何标签。

Whole-Model Template

 

Whole-Model Template 主要包括:

Html.DisplayForModel()

根据当前model每个property的类型,生成相应html(只读)

Html.EditForModel()

根据当前model的每个property的类型,生成相应可编辑的html

Html.LabelForModel()

根据当前的model生成标签

 

使用Html.EditForModel重构View代码:

@using(Html.BeginRouteForm("FormRoute", new {},FormMethod.Post,
new { @class = "personClass",data_formType="person"})) {
@Html.EditorForModel()
<input  type="submit" value="Submit" />
}


运行,查看结果


使用model metadata

1.      hiddenInput

给PersonId加一个属性:

[HiddenInput(DisplayValue=false)]

运行,测试:


点击submit

Debug查看Person的值,可以看到PersonId被提交了,值为100。原因是我们的attribute告诉mvcframework把这个input解析为Hidden,查看html:

<input data-val="true" data-val-number="The field PersonId must be a number. " data-val-required="The PersonId field is required." id="PersonId" name="PersonId"  type="hidden" value="100"/>


可以看到,type已经被解析为了hidden

 

使用[ScaffoldColumn]属性

 

一个类中不是每个字段都是需要mvc frame解析为html的,如果希望跳过某个property,可以使用这个属性。例如:

[ScaffoldColumn(false)]
public int PersonId { get; set; }


这样的话,PersonId根本不会参与从property解析到html的过程。

 

使用[Display(Name=”XXX”)]

 

如果希望html解析出来的Label显示成别的字,可以使用这个属性。例如:

[Display(Name = "Birth Date")]
public DateTime BirthDate { get; set; }


对应的html标签:

<label for="BirthDate">BirthDate</label>


 

使用 [DataType(type)]

 

如果想改变mvc frame 解析的类型,可以使用此属性,例如:

[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }


这样mvc解析这个property就会当做Date类型,而不是DateTime了。

相应的html标签:

<input  class="text-boxsingle-line" data-val="true"  data-val-date="The field BirthDate mustbe a date." data-val-required="The BirthDate field is required." id="BirthDate" name="BirthDate" type="date"  value="13/4/1994" />


 

其他DataType可以选择的类型

DateTime

Date

Time

Text

PhoneNumber

MultipleText

Password

Url

EmailAddress

 

使用[UIHint(“XX”)]属性

UIHint属性允许指定一个模板名称,mvc framework解析的时候,看到这个属性就会先找到对应的模板,再解析为相应的html,例如:


[UIHint("MultilineText")] 
public  string FirstName { get; set; }



相应的html:

<textarea class="text-box multi-line" id="FirstName" name="FirstName">
iori</textarea>


 

MVC 自带的模板

Boolean

DateTime

Date

EmailAddress

HiddenInput

Html

MultiLineText

Number

Object

Password

String

Time

Text

Tel

Url

 

Mvc会为每个模板生成对应的html,读者可以一一尝试,根据自己的需要选择的应用到项目中。每个模板,也是可以被重写的。

 

使用metadata类

1 .  修改Person类为partial,去掉所有的DataType,Hint(就像一个Entity类):


  public int PersonId{ get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
        public Address HomeAddress { get; set; }
        public bool IsApproved { get; set; }
        public Role Role { get; set; }


 

 

为了给Person类应用metadata 类型,需要先将其设为partial

2.      创建一个metadata 类

public partial class PersonMetaData {
[HiddenInput(DisplayValue=false)]
public int PersonId { get; set; }
[Display(Name="First")]
public string FirstName { get; set; }
[Display(Name = "Last")]
public string LastName { get; set; }
}


 

3.      在Person类加上metadatatype属性

[MetadataType(typeof(PersonMetaData))]

4.      View 中使用EditFormModel

@using(Html.BeginRouteForm("FormRoute",new {}, FormMethod.Post,
new { @class = "personClass",data_formType="person"})) {
   @Html.EditorForModel()
<input  type="submit" value="Submit" />
}


 

使用metadata类的目的,希望Entity类和MVC Attribute标记过的类分开,但显示的时候,希望MVCFramework会从medadata类中找到一致的Property,拿出Attribute应用。运行,查看效果,


可以看到标签名字变了,PersonId也隐藏了,因此Metadata类的Display标签和Hidden标签都产生了效果。

 

解析嵌套类型 : Address

前面的例子,由于HomeAddress字段是class,因此MVCFramework没有识别出来,因此需要手动去再调用一下EditFor:

  <p>
       @Html.EditorFor(m => m.HomeAddress)
</p>


 

运行:


可以看到这样Address类型就可以被识别了。

 

显示指定Template

Html.EditorFor(m =>m.SomeProperty,  "MyTemplate")

可以告诉MVC Framework,使用指定的Template。

Template的查找顺序

1.      Customize的template

2.      Built-in的template

3.      传入Helper的Template,e.g. : Html.EditorFor(m=>m.name,”T”);

4.      UIHint

5.      DataType

Customize一个Template

在Shared文件夹建一个EditorTemplates文件夹,因为所有的customize的template,MVCFramework都会来这里找。

创建一个View放在EditorTemplates文件夹,可以反射出枚举的每一个成员并显示:

@model Enum
@Html.DropDownListFor(m => m,Enum.GetValues(Model.GetType())
.Cast<Enum>()
.Select(m => {
string enumVal =Enum.GetName(Model.GetType(), m);
return new SelectListItem() {
Selected = (Model.ToString() ==enumVal),
Text = enumVal,
Value = enumVal
};
}))


 

应用,在metadata类给Role成员加UIHint

[UIHint("Enum")]
public Role Role { get; set; }


 

运行,查看结果


可以看到,自定义的Template成功的工作了。

 

 

相关文章:

  • 主流杀毒软件多已支持windows7
  • IE 异常_doPostBack is undefined
  • 推荐一款很经典的网络电话——阿里通网络电话
  • Asp.Net MVC4系列--进阶篇之AJAX
  • Asp.Net MVC4 系列--进阶篇之Model(1)
  • Windows 7安装过程全体验!(42图)
  • Asp.Net MVC4 系列--进阶篇之Model(2)
  • Windows7下系统实用小工具
  • log4net 使用与配置 每天一份log文件
  • 近期阅读关注(200903)
  • VHD(虚拟磁盘)系统在Windows 7中的加载
  • 图解 Windows 7 Native Boot 全教程
  • Javascript Learning Function(2)
  • Windows 7新功能深入体验
  • Windows 7一些优化调整技巧
  • 〔开发系列〕一次关于小程序开发的深度总结
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Brief introduction of how to 'Call, Apply and Bind'
  • HTML中设置input等文本框为不可操作
  • Joomla 2.x, 3.x useful code cheatsheet
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • python学习笔记-类对象的信息
  • Ruby 2.x 源代码分析:扩展 概述
  • Shell编程
  • Transformer-XL: Unleashing the Potential of Attention Models
  • web标准化(下)
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 每天一个设计模式之命令模式
  • 通信类
  • 微信公众号开发小记——5.python微信红包
  • 异常机制详解
  • #ifdef 的技巧用法
  • #pragam once 和 #ifndef 预编译头
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转载)利用webkit抓取动态网页和链接
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • @Bean, @Component, @Configuration简析
  • @FeignClient注解,fallback和fallbackFactory
  • @Transaction注解失效的几种场景(附有示例代码)
  • [ANT] 项目中应用ANT
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计
  • [C++打怪升级]--学习总目录
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [NOI2012]迷失游乐园