ASP.NET MVC Model元数据(三)

58 篇文章 0 订阅
39 篇文章 0 订阅

 

ASP.NET MVC Model元数据(三)

前言

在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会对Model元数据本身的结构稍作讲解,读完本篇过后你将会对Model元数据的结构有个很清晰的印象。

 

Model元数据

  • 什么是Model元数据?
  • 生成Model元数据的过程【一】
  • 生成Model元数据的过程【二】
  • ModelMetaData的定义、详解
  • Model元数据应用(常用特性应用)-1
  • Model元数据应用(自定义视图模板)-2
  • Model元数据应用(IMetadataAware接口使用)-3

 

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

还记得Model元数据系列篇的第一章里的最后一幅图吗?

图1

 

没有错,MVC框架根据我们定义的视图模型生成了一个Model元数据ModelMetadata(实际为DataAnnotationsModelMetadata类型是继承自ModelMetadata类型的,在下文中为了更直观的方便讲解所以还是用ModelMetadata类型来作介绍)。我们来看一下ModelMetadata类型的定义:

代码1-1

public class ModelMetadata
    {
        
        
        public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
        //
        // 摘要:
        //     获取模型元数据对象的集合,这些对象描述模型的属性。
        //
        // 返回结果:
        //     用于描述模型属性的模型元数据对象的集合。
        public virtual IEnumerable<ModelMetadata> Properties { get; }
//
        // 摘要:
        //     获取模型的类型。
        //
        // 返回结果:
        //     模型的类型。
        public Type ModelType { get; }
        protected ModelMetadataProvider Provider { get; set; }
        ……
    }

只留了个构造函数和三个属性,详细的部分下篇会讲到,构造函数中的第一个参数类型大家肯定很熟悉,那就是上篇中讲到的Model元数据生成程序,用来生成Model元数据(ModelMetadata类型)的,这样的是把ModelMetadataProvider类型的引用设置到Model元数据的内部,也就是Provider属性,这样做是有目的的随后就会讲到,在其定义中还有个Properties属性,类型大家都看到了是ModelMetadata类型的集合,这就是ModelMetadata类型关键的所在了,Properties属性表示着当前ModelMetadata的所描述类型中的属性元数据集合。

图2

用前篇介绍过的Customer类型来做描述,对应着Customer类型的结构MVC框架也会生成对应的ModelMetadata类型结构,这里捎带提一下,对于Address属性类型是Address类型这种属于复杂类型,MVC框架会向下继续生成就如同生成Customer类型一样。

那么这样的结构是怎么生成的呢?当然不用说了,是依靠Provider属性也就是ModelMetadataProvider类型的引用来生成结构的,如图3所示:

图3

首先根据当前Model元数据ModelMetadata类型(对应的对象是Customer类型)中的Model属性和ModelType属性来作为参数调用AssociatedMetadataProvider类型的GetMetadataForProperties()方法,这里说一下ModelMetadata类型的Model属性,表示着当前Model元数据所对应对象的值,也是用这个值来判断是否是复杂类型的,ModelType属性上面说过。

在GetMetadataForProperties()方法中会先根据自定义类型描述类型的GetProperties()方法来获取当前对象是Customer类型的所有的属性,并且封装成属性描述类型集合。

随后根据获取到的属性描述类型集合,遍历此集合并且根据遍历中的单个属性描述类型调用AssociatedMetadataProvider类型中的GetMetadataForProperty()方法,这里要说的是第一个参数modelAccessor默认是Null的,第二个参数containerType是表示着当前Customer类型,第三个参数就是属性描述类型了里面包含着属性类型的所有信息。有的朋友会问说明这些属性做什么,因为等下会说到第二个参数containerType的。

在AssociatedMetadataProvider类型中的GetMetadataForProperty()方法中,会根据PropertyDescriptor类型的参数获取到当前属性上所有描述信息(也就是那些特性类),比如当前的PropertyDescriptor类型是结构化Customer类型中的CustomerID,那图3中AttrbuteList类型中就是包含着所有依附在这个属性上的特性类。后续的生成过程还是跟上篇的讲解的一样依旧的调用了AssociatedMetadataProvider类型的CreateMetadata(),只不过在AssociatedMetadataProvider类型中方法是抽象中,实际是由它的实现类DataAnnotationsModelMetadataProvider中的CreateMetadata()方法来完成的。

这里大家可能会发现,在图3中黄色框中的操作都是属于遍历中的操作,就是每次都会只会生成一个ModelMetadata类型实例然后最后合并在一起返回出去。

还有要说的就是在图3中黄色框中的每个调用的函数都有个Type类型的containerType参数,这就是上面说过的Customer类型,并且在生成的ModelMetadata类型实例中赋值到ContainerType属性,表示着新生成的ModelMetadata类型实例比如叫A,A中描述的信息就是Customer类型中的CustomerID属性的所有信息,而A中的ContainerType属性就是表示描述的CustomerID属性是属于哪个类型的。

这里还有要说的,就是在系统默认生成的时候,比如说视图模型是Customer类型,那么MVC框架只会生成一个ModelMetadata类型的实例假使它叫M,因为M自身并没有自己检测自己是不是复杂类型,所以M是不会调用提供器往下生成的,而是在外部要使用M了才会去调用M中的函数检测M是不是复杂类型然后往下生成,假使现在MVC框架中使用到了这个M可能就会调用检测它自身的方法来检查它是不是复杂类型,明显的Customer类型是复杂类型,这个时候M会按照本篇描述的那样依次的生成它所描述类型中的属性,也只是仅限于这一层,有的朋友可能会问在Customer类型中Address属性也是复杂类型,对的,但是M只会去生成Address属性本身的ModelMetadata类型的实例,而不会去生成Address属性的内部。

现在大家再看一次图2,是不是有点清晰的感觉。

(有哪位大神知道在MVC框架中是在哪里调用ModelMetadata类型实例的自身检测的?知道的告知一下小弟以身相许,找的头破血流也没找到,我相信是肯定有的)

本篇结束,下篇中详细介绍DataAnnotationsModelMetadataProvider类型中的CreateMetadata()方法,从这个方法进入,详细的讲解ModelMetadata对象类型。


 

作者:金源

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET MVC 5 框架揭秘》以一个模拟ASP.NET MVC内部运行机制的“迷你版MVC框架”作为开篇,其目的在于将ASP.NET MVC真实架构的“全景”勾勒出来。接下来本书以请求消息在ASP.NET MVC框架内部的流向为主线将相关的知识点串连起来,力求将”黑盒式”的消息处理管道清晰透明地展示在读者面前。相信精读本书的读者一定能够将ASP.NET MVC从接收请求到响应回复的整个流程了然于胸,对包括路由、Controller的激活、Model元数据的解析、Action方法的选择与执行、参数的绑定与验证、过滤器的执行以及View的呈现等相关的机制具有深刻的理解。 本书以实例演示的方式介绍了很多与ASP.NET MVC相关的很好实践,同时还提供了一系列实用性的扩展,相信它们一定能够解决你在真实开发过程中遇到的很多问题。本书末章提供的案例不仅仅用于演示实践中的ASP.NET MVC,很多的架构设计方面的东西也包含其中。除此之外,本书在很多章节还从设计的角度对ASP.NET MVC的架构进行了深入分析,所以从某种意义上讲本书可以当成一本架构设计的书来读。 ASP.NET MVC 5 框架揭秘 目录 第1章 ASP.NET + MVC 第2章 路由 第3章 Controller的激活 第4章 Model元数据的解析 第5章 3个描述对象 第6章 Model的绑定(上篇) 第7章 Model的绑定(下篇) 第8章 Model的验证(上篇) 第9章 Model的验证(下篇) 第10章 Action方法的执行 第11章 View的呈现 第12章 过滤器 第13章 特性路由 第14章 案例实践
蒋金楠编的《ASP.NET MVC5框架揭秘》以一个 模拟ASENET MVC内部运行机制的“迷你版MVC框架” 作为开篇,其目的在于将ASENET MVC真实架构的“全 景”勾勒出来。接下来本书以请求消息在ASENET MVC 框架内部的流向为主线将相关的知识点串联起来,力 求将“黑盒式”的消息处理管道清晰透明地展示在读 者面前。相信精读本书的读者一定能够将ASENET MVC :从接收请求到响应回复的整个流程了然于胸,对包 括路由、Controller的激活、Model元数据的解析、 Action方法的选择与执行、参数的绑定与验证、过滤 器的执行及View的呈现等相关机制具有深刻的理解。   本书以实例演示的方式介绍了很多与ASENET MVC 相关的*佳实践,同时还提供了一系列实用性的扩展 ,相信它们一定能够解决你在真实开发过程中遇到的 很多问题。本书*后一章提供的案例不仅用于演示实 践中的ASENET MVC很多架构设计方面的东西也包含其 中。除此之外,本书在很多章节还从设计的角度对 ASENET MVC的架构进行了深入分析,所以从某种意义 上讲本书可以当成一本架构设计的书来读。   虽然与市面上任何一本相关的书相比,本书走得 *远,并*加近 距离地触及ASENET MVC框架的内核, 但是就其内容本身来讲却没有涉及太多“高深莫测” 的知识点,所以阅读本书不存在太高的门槛。如果你 觉得自己对ASENET MVC所知甚少,可以利用此书来系 统地学习ASENET MVC;如果你觉得自己对ASENET MVC足够精通,一定能够在此书中找到相应的“盲点 ”。 《ASP.NET MVC 5 框架揭秘》以一个模拟ASP.NET MVC内部运行机制的“迷你版MVC框架”作为开篇,其目的在于将ASP.NET MVC真实架构的“全景”勾勒出来。接下来《ASP.NET MVC 5 框架揭秘》以请求消息在ASP.NET MVC框架内部的流向为主线将相关的知识点串联起来,力求将“黑盒式”的消息处理管道清晰透明地展示在读者面前。相信精读《ASP.NET MVC 5 框架揭秘》的读者一定能够将ASP.NET MVC从接收请求到响应回复的整个流程了然于胸,对包括路由、Controller的激活、Model元数据的解析、Action方法的选择与执行、参数的绑定与验证、过滤器的执行及View的呈现等相关机制具有深刻的理解。, 《ASP.NET MVC 5 框架揭秘》以实例演示的方式介绍了很多与ASP.NET MVC相关的最佳实践,同时还提供了一系列实用性的扩展,相信它们一定能够解决你在真实开发过程中遇到的很多问题。《ASP.NET MVC 5 框架揭秘》最后一章提供的案例不仅用于演示实践中的ASP.NET MVC,很多架构设计方面的东西也包含其中。除此之外, 《ASP.NET MVC 5 框架揭秘》在很多章节还从设计的角度对ASP.NET MVC的架构进行了深入分析,所以从某种意义上讲本书可以当成一本架构设计的书来读。, 虽然与市面上任何一本相关的书相比,《ASP.NET MVC 5 框架揭秘》走得更远,并更加近距离地触及ASP.NET MVC框架的内核,但是就其内容本身来讲却没有涉及太多“高深莫测”的知识点,所以阅读《ASP.NET MVC 5 框架揭秘》不存在太高的门槛。如果你觉得自己对ASP.NET MVC所知甚少,可以利用《ASP.NET MVC 5 框架揭秘》来系统地学习ASP.NET MVC;如果你觉得自己对ASP.NET MVC足够精通,一定能够在《ASP.NET MVC 5 框架揭秘》中找到相应的“盲点”。
蒋金楠编*的《ASP.NET MVC5框架揭秘》以一个 模拟ASENET MVC内部运行机制的“迷你版MVC框架” 作为开篇,其目的在于将ASENET MVC真实架构的“全 景”勾勒出来。接下来本书以请求消息在ASENET MVC 框架内部的流向为主线将相关的知识点串联起来,力 求将“黑盒式”的消息处理管道清晰透明地展示在读 者面前。相信精读本书的读者一定能够将ASENET MVC :从接收请求到 响应回复的整个流程了然于胸,对包 括路由、Controller的激活、Model元数据的解析、 Action方法的选择与执行、参数的绑定与验证、过滤 器的执行及View的呈现等相关机制具有深刻的理解。   本书以实例演示的方式介绍了很多与ASENET MVC 相关的*佳实践,同时还提供了一系列实用性的扩展 ,相信它们一定能够解决你在真实开发过程中遇到的 很多问题。本书*后一章提供的案例不仅用于演示实 践中的ASENET MVC很多架构设计方面的东西也包含其 中。除此之外,本书在很多章节还从设计的角度对 ASENET MVC的架构进行了深入分析,所以从某种意义 上讲本书可以当成一本架构设计的书来读。   虽然与市面上任何一本相关的书相比,本书走得 *远,并*加近距离地触及ASENET MVC框架的内核, 但是就其内容本身来讲却没有涉及太多“高深莫测” 的知识点,所以阅读本书不存在太高的门槛。如果你 觉得自己对ASENET MVC所知甚少,可以利用此书来系 统地学习ASENET MVC;如果你觉得自己对ASENET MVC足够精通,一定能够在此书中找到相应的“盲点 ”。
ASP.NET MVC 中添加数据,你需要遵循以下步骤: 1. 创建一个模型类,定义你要添加的数据的属性,例如: ```csharp public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } ``` 2. 创建一个控制器类,并添加一个方法来处理添加数据的请求,例如: ```csharp public class ProductsController : Controller { private readonly ApplicationDbContext _context; public ProductsController(ApplicationDbContext context) { _context = context; } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(Product product) { if (ModelState.IsValid) { _context.Add(product); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(product); } } ``` 3. 创建一个视图来显示添加数据的表单,例如: ```html @model Product <form asp-action="Create"> <div class="form-group"> <label asp-for="Name" class="control-label"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Price" class="control-label"></label> <input asp-for="Price" class="form-control" /> <span asp-validation-for="Price" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> ``` 4. 添加路由,以便能够从浏览器中访问到添加数据的页面,例如: ```csharp app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute( name: "create", pattern: "products/create", defaults: new { controller = "Products", action = "Create" }); }); ``` 现在你可以通过访问 /products/create 来打开添加数据的页面,在表单中输入数据并提交,数据将会被添加到数据库中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值