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

ASP.NET MVC Model元数据(五)


ASP.NET MVC Model元数据(五)

前言

在上一篇中我们描述了应用于Model上面的各种用于显示控制的特性类,在本篇中将详细的介绍这些特性类的应用,虽然它们跟Model元数据的直接关系并不大,但是我们可以用它们在编码阶段控制运行时的显示。

 

Model元数据

  • 什么是Model元数据?

  • 生成Model元数据的过程【一】

  • 生成Model元数据的过程【二】

  • ModelMetaData的定义、详解

  • Model元数据应用(常用特性应用)-1

  • Model元数据应用(自定义视图模板)-2

  • Model元数据应用(IMetadataAware接口使用)-3

Model元数据应用(常用特性应用)-1

所用示例:

代码1-1

1
2
3
4
5
6
7
8
9
10
11
     public  class  Customer
     {
         public  string  CustomerID {  get set ; }
         public  string  Name {  get set ; }
         public  DateTime RegistrationDate{  get set ; }
         public  Address Address {  get set ; } 
     }
     public  class  Address
     {
         public  string  AddressName {  get set ; }
     }

这是下面所要用的示例Model,下面的代码1-2示例是使用自定义模型绑定器用于获取Model数据的,大家只需要看数据的值就行了,对于Model绑定部分后续的篇幅的中再介绍。

代码1-2

1
2
3
4
5
6
7
8
9
10
11
12
13
         public  object  BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
         {
             return  new  Customer()
             {
                 CustomerID =  "010" ,
                 Name =  "测试人员" ,
                 RegistrationDate = DateTime.Now,
                 Address =  new  Address()
                 {
                     AddressName =  "天空之城"
                 }
             };
         }

 

HiddenInputAttribute

HiddenInputAttribute类型所表示的意思是将应用的属性显示为隐藏输入域类型(Hidden),其中包含一个属性DisplayValue表示是否显示这个隐藏的输入域,我们修改一下代码1-1中的内容:

代码1-3

1
2
[HiddenInput(DisplayValue= true )]
public  string  CustomerID {  get set ; }

然后看一下我们在视图界面的代码:

代码1-4

1
2
3
4
5
6
@model ConsoleApplication2.Customer
@{
     ViewBag.Title = "Show";
}
< h2 >Show</ h2 >
< p >@Html.EditorForModel()</ p >

结果如图1.

图1

在图1中我们看到CustomerID对应的属性值&ldquo;010&rdquo;在页面里显示为只读的文本状态,生成的Html代码如下:

1
< input  name = "CustomerID"  id = "CustomerID"  type = "hidden"  value = "010" />

修改代码1-3中的DisplayValue属性值为true后,视图部分的代码不变,运行结果如图2。

图2

在图2中,已经看不到CustomerID属性所表示的项了,看到这里相信我们已经了解了HiddenInputAttribute类型的使用了吧。

 

DataTypeAttribute

看上面的图2 ,RegistrationDate属性所对应的值都是日期时间格式的,那怎么控制属性值的输入样式呢?比如说想让属性值显示为日期类型,来看代码1-5

代码1-5

1
2
[DataType(DataType.Date)]
public  DateTime RegistrationDate{  get set ; }

视图部分的代码不用改变来看一下结果图3

图3

从上图中看出输出值的格式样式已经改变了。

 

DisplayAttribute

DisplayAttribute类型用于指示的属性所显示的标签值的修改,比如说图3中的Name和RegistrationDate,想显示我们成我们自定义的名称就要用DisplayAttribute类型,来看代码1-6.

代码1-6

1
2
3
4
5
[Display(Name= "姓名" )]
public  string  Name {  get set ; }
[DataType(DataType.Date)]
[Display(Name= "注册日期" )]
public  DateTime RegistrationDate{  get set ; }

视图部分的代码依旧不变,我们来看一下运行的结果图4。

图4

从图4我们已经看到更改了

 

Model元数据应用(自定义视图模板)-2

UIHintAttribute

本小节对视图模板和UIHintAttribute类型的使用做一些简单的介绍。

视图模板是什么意思呢?就是根据Model元数据提供的信息生成为指定的视图模板所对应的Html代码(包含Html元素样式),我们看一下示例,这样比较直观。

代码2-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     public  class  Customer
     {
         [HiddenInput(DisplayValue= false )]
         public  string  CustomerID {  get set ; }
 
         [Display(Name= "姓名" )]
         [UIHint( "Password" )]
         public  string  Name {  get set ; }
 
         [DataType(DataType.Date)]
         [Display(Name= "注册日期" )]
         public  DateTime RegistrationDate{  get set ; }
 
         public  Address Address {  get set ; } 
     }

从代码2-1中的Name属性上看到UIHintAttribute类型的特性,使用它的意思就是指定一个视图模板来为这个属性生成Html代码,这样为了直观的可以看出来所以使用了Password视图模板,这个Password视图模板的意思讲Model元数据所对应的属性值生成为一个单行的文本框Input元素,并且元素中的字符是不可见的,是可编辑的。看一下结果图5.

图5

所对应的Html代码2-2

代码2-2

1
< input  name = "Name"  class = "text-box single-line password"  id = "Name"  type = "password"  value = "测试人员" />

 

系统为我们提供了许多视图模板,但是也不能乱用的,要保持使用的视图模板所需类型和指定的属性一致的。

 

自定义视图模板

细心的朋友可能会发现在上面的显示页面中都没有发现Address属性的值,这个在前篇就强调过,因为Address属性对应的类型在生成Model元数据的时候被判别为复杂类型,而模板视图辅助器是不会去对复杂类型进行处理的,那我们要怎么显示Address属性中的值呢?

我们使用自定义的视图模板,当然作用不止这么一点,只是用来讲解而已。

首先项目中的/Views/Shared的目录下新建一个名为EditorTemplates的文件夹,然后在此文件夹中新建一个强类型的分布视图文件,类型是指定属性对应的类型,并且命名视图文件为指定属性的类型名称,按照示例来说就是Address类型的名称就是Address,完成后应该是这样的,图6

图6

在此视图中添加如代码2-3。

代码2-3

1
2
3
4
< p >
@Html.LabelFor(m=>m.AddressName)
@Html.EditorFor(m => m.AddressName)
</ p >

然后修改代码2-1中的Address属性,并且修改Address类型里的AddressName属性要显示的名称,用我们上面讲过的DisplayAttribute类型示例代码2-4

代码2-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
     public  class  Customer
     {
         [HiddenInput(DisplayValue= false )]
         public  string  CustomerID {  get set ; }
 
         [Display(Name= "姓名" )]
         [UIHint( "Password" )]
         public  string  Name {  get set ; }
 
         [DataType(DataType.Date)]
         [Display(Name= "注册日期" )]
         public  DateTime RegistrationDate{  get set ; }
 
         [UIHint( "Address" )]
         public  Address Address {  get set ; } 
     }
     public  class  Address
     {
         [Display(Name= "地址名称" )]
         public  string  AddressName {  get set ; }
     }

然后再修改掉我们主视图页面的代码,使用EditFor辅助器单独的对Address属性进行处理操作,如代码2-5所示。

代码2-5

1
2
3
4
5
6
7
@model ConsoleApplication2.Customer
@{
     ViewBag.Title = "Show";
}
< h2 >Show</ h2 >
< p >@Html.EditorForModel()</ p >
< p >@Html.EditorFor(m=>Model.Address)</ p >

然后我们看一下修改后的结果图7.

图7

还有一些其他的特性类型的使用示例会在以后修改本篇,现在本人也不是太熟不能乱写的。

 

Model元数据应用(IMetadataAware接口使用)-3

前面的篇幅对Model元数据的生成的详细过程以及使用都有所粗略的讲解,想必这时大家已经对Model元数据有所了解了,这个小节介绍如何使用IMetadataAware接口类型来实现我们直接操作Model元数据,从而跳过那些使用系统自带的那些特性类,它们是可以先设置,但是我们也可以自定义的设置Model元数据的值,好了废话不多说了往下看吧。

 

在Model元数据(二)的篇幅里,我们提到过的内容中,在Model元数据生成后的最后一步过程是会调用Model元数据生成提供程序中的一个函数,在此函数中MVC框架会检索当前Model元数据所指定的类型上的所有特性类型集合,检索出实现了IMetadataAware接口的特性类,然后使用这个实现类型对当前Model元数据进行操作。可能朋友们看我的这段叙述有点模糊,那我们直接来看示例代码吧。

首先我们定义个类型来实现IMetadataAware接口类型,而根据MVC框架检索的前提约定,我们需要把自定义的类型定义为特性类,如代码3-1所示:

代码3-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Property,AllowMultiple= false ,Inherited= false )]
     public  class  MyCustomMetadataAware:Attribute,IMetadataAware
     {
         public  void  OnMetadataCreated(ModelMetadata metadata)
         {
             if  (metadata !=  null )
             {
                 if  (metadata.DisplayName ==  "地址名称" )
                 {
                     metadata.DisplayName =  "经过IMetadataAware修改的地址名称" ;
                 }
             }
         }
     }

在代码3-1中,我们自定义的类型MyCustomMetadataAware实现了IMetadataAware接口类型,并且在OnMetadataCreated()方法中对metadata参数(Model元数据)进行修改,修改的属性DisplayName是Model元数据控制器对应属性显示的名称,在这个MyCustomMetadataAware类型中我们把这个DisplayName属性值如果符合某种条件下修改掉(为了配合上面的示例)。

我们再来看一下我们的Model定义,如代码3-2:

代码3-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  class  Customer
     {
         [HiddenInput(DisplayValue= false )]
         public  string  CustomerID {  get set ; }
 
         [Display(Name= "姓名" )]
         [UIHint( "Password" )]
         public  string  Name {  get set ; }
 
         [DataType(DataType.Date)]
         [Display(Name= "注册日期" )]
         public  DateTime RegistrationDate{  get set ; }
 
         [UIHint( "Address" )]
         public  Address Address {  get set ; } 
     }
     public  class  Address
     {
         [Display(Name= "地址名称" )]
         [MyCustomMetadataAware]
         public  string  AddressName {  get set ; }
     }

在代码3-2中,我们把Model中的Address属性所对应的Address类型中的AddressName属性加上了我们自定义的特性类,意在修改这个属性最后在页面上显示出来的值。

我们看一下修改后的结果图8.

图8

从图8中我们可以清楚的看到对应地址栏的标签名称已经被修改掉了,对于系统提供的这个IMetadataAware接口我们可以做更多的自定义操作,这种方式的编程模式我们也是很常见的。

 

Model元数据部分到这里就全部结束了,其中也会有很多细节的部分没有讲的很到位、没有很全面,因为博主是小白有什么写的不好的地方朋友们可以提出来,我会学习并且再来回的修改篇幅,能在这里为大家尽一点薄力感到很荣幸,也谢谢大家的支持。下一个系列将是Model绑定的部分,大家敬请期待。




     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1430958,如需转载请自行联系原作者




相关文章:

  • Android 解决ListView 和 ScrollView 共存冲突的问题
  • [Web开发] Web 2.0 网站估价工具
  • c#中的反射机制
  • 利用QRmaker制作二维码
  • CentOS 6.8 部署django项目二
  • GHOST
  • 磁盘与文件系统管理之五
  • SQL Server 2008 存储结构之DCM、BCM
  • 网络管理员的基本素质
  • 一步一步学会puppet(二)--模块和类
  • DHCP用户类选项配置
  • [Unity3d]安卓无法加载assetbundle的问题
  • jquery.idTabs使用方法
  • Windows Workflow Foundation学习资源
  • lvs-nat负载均衡模式
  • [LeetCode] Wiggle Sort
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • ERLANG 网工修炼笔记 ---- UDP
  • gf框架之分页模块(五) - 自定义分页
  • Golang-长连接-状态推送
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Java 23种设计模式 之单例模式 7种实现方式
  • javascript面向对象之创建对象
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Js基础知识(四) - js运行原理与机制
  • spark本地环境的搭建到运行第一个spark程序
  • Tornado学习笔记(1)
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 基于 Babel 的 npm 包最小化设置
  • 精彩代码 vue.js
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 每天一个设计模式之命令模式
  • 推荐一个React的管理后台框架
  • 数据可视化之下发图实践
  • ​2020 年大前端技术趋势解读
  • ​MySQL主从复制一致性检测
  • (zhuan) 一些RL的文献(及笔记)
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (论文阅读30/100)Convolutional Pose Machines
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)用.Net的File控件上传文件的解决方案
  • (转载)Linux网络编程入门
  • .aanva
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [《百万宝贝》观后]To be or not to be?
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [Bugku]密码???[writeup]
  • [GN] Vue3.2 快速上手 ---- 核心语法2
  • [HNCTF 2022 WEEK2]easy_include 文件包含遇上nginx
  • [IE技巧] IE8中HTTP连接数目的变化
  • [JDBC-1] JDBC Base Template
  • [jobdu]不用加减乘除做加法
  • [MFC] MFC消息机制的补充
  • [one_demo_18]js定时器的示例