ASP.NET MVC5 ModelBinder

什么是ModelBinding

ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应。为了能够正确处理请求,Action的参数(如果有的话),必须在Action执行之前,根据相应的规则,把请求中所包含的数据提取出来并将映射为Action的参数值,这个过程就是ModelBinding。ModelBinding的作用就是为Action提供参数列表。

ModelBinding的好处

  1. 使代码变得更加简洁
  2. 帮助我们获取HTTP请求中的数据
  3. 帮助我们完成必要的数据类型转换

ASP.NET MVC中ModelBinding的实现过程

ASP.NET MVC中ModelBinding的实现过程比较复杂,这里简要说明它的总体流程。具体的实现过程可以看蒋金楠的《ASP.NET MVC5框架揭秘》或者看他的博客How ASP.NET MVC Works?,讲解很详细。


  • HTTP请求中的数据可能存在于querystring中,也可能在表单中,也有可能是JSON字符串。究竟从哪里获取数据,这要依赖于参数的描述信息ParameterDescriptor
  • ParameterDescriptor的获取需要借助于ControllerDescriptorActionDescriptor,它们分别用来描述Controller和Action
  • IModelBinderProvider用于提供合适的ModelBinder对象,我们可以自己实现该接口以获取自定义的IModelBinder
  • ModelBinding的核心IModelBinder,默认实现类是DefaultModelBinder,我们可以自己实现IModelBinder接口来扩展ModelBinder
  • IValueProvider针对不同的数据源提供了数据的访问机制
  • ValueProviderResult提供了两个ConvertTo方法重载以实现向指定目标类型的转换。
  • 经过上述一系列的处理获取最终结果

自定义ModelBinder

自定义Modelbinder只需实现System.Web.Mvc.IModelBinder接口即可。这里需要注意一点,System.Web.ModelBinding命名空间下也有一个IModelBinder接口,不要搞错了。

public class LessonEditInfoViewModelBinder : IModelBinder
{//根据前台传递的id值获取对象public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext){var idStr = controllerContext.HttpContext.Request["id"] ?? controllerContext.RouteData.Values["id"]?.ToString();int id = 0;if (!int.TryParse(idStr, out id)){return null;}var model = new LessonBLL().GetLessonEditInfo(id);return model;}
}

然后使用ModelBinderAttribute进行标注即可:

/*根据前台传递的id值解析出对象数据,Action无需关注对象的获取,使代码变得清晰简洁
*/
public ActionResult Edit([ModelBinder(typeof(LessonEditInfoViewModelBinder))]LessonEditInfoViewModel lesson)
{if (lesson == null){//跨控制器的视图跳转要使用视图的路径+文件名return View("/Views/Exception/GenericError.cshtml", new ExceptionViewModel { Title = "404", Description = "课程不存在!" });}return View(lesson);
}

如果项目中多处需要使用自定义的ModelBinder,那么再使用ModelBinderAttribute进行标注就不大合适了。这种情况我们可以使用自定义的ModelBinderProvier。代码如下:

public class CustomeModelBinderProvider : IModelBinderProvider
{public IModelBinder GetBinder(Type modelType){if (modelType == typeof(LessonEditInfoViewModel)){return new LessonEditInfoViewModelBinder();}return null;}
}

然后将自定义的ModelBinderProvider注册到ASP.NET MVC系统中

public class MvcApplication : System.Web.HttpApplication
{protected void Application_Start(){ModelBinderProviders.BinderProviders.Insert(0, new CustomeModelBinderProvider());}
}

完成上述两步之后,就无需使用ModelBuilderAttribute进行标注了。

除此之外,还可在Global文件中使用使用ModelBinder类的Binder属性来注册ModelBinderProvider

ModelBinders.Binders.Add(typeof(LessonEditInfoViewModel),new LessonEditInfoViewModelBinder());

不同的ModelBinder提供策略有不同的优先级,具体如下:

  1. 在参数上使用CustomModelBinderAttribute
  2. 使用ModelBinderProviders.BinderProviers
  3. 使用ModelBinders.Binders
  4. 参数类型上标记CustomModelBinderAttribute
  5. ASP.NET MVC中提供的DefaultModelBinder

注意,CustomModelBinderAttribute是抽象类,在ASP.NET MVC中有唯一子类ModelBinderAttribute。

参考文章:

Model Binders in ASP.NET MVC
ModelBinder——ASP.NET MVC Model绑定的核心
ASP.NET MVC以ValueProvider为核心的值提供系统
玩转Asp.net MVC 的八个扩展点
ASP.NET MVC中你必须知道的13个扩展点

版权声明

本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接。

如有问题, 请发送邮件和作者联系。

转载于:https://www.cnblogs.com/Cwj-XFH/p/5977508.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457117.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day07-函数(2)

1.函数类型 函数也是一种类型,我们自定义的函数就是函数对象,函数名保存了函数对象的引用(地址) def test():print(我是测试函数) ​ print(test) #函数名是变量,指向了函数对象 pf test #pf变量也指向了函数对…

php在html里面的位置,关于script在html中的摆放位置解析

以前一直觉得script在html中的任何位置都可以,今天做一个需求的时候才更正了自己的错误思想啊--script的位置也不是随便放的。本文主要谈论关于script在html中的摆放位置。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。希望能帮助到…

Protocol Buffer技术详解(C++实例)

原文:http://www.cnblogs.com/stephen-liu74/archive/2013/01/04/2842533.html 这篇Blog仍然是以Google的官方文档为主线,代码实例则完全取自于我们正在开发的一个Demo项目,通过前一段时间的尝试,感觉这种结合的方式比较有利于培训…

yaml 解决问题

yaml 是什么? 在 github 一些开源项目里经常可以看到 .travis.yml 文件,后来接触持续集成这个概念时发现很多文件都是 .yml 后缀的文件。我在 阮一峰-YAML 语言教程 里了解了它的作用以及基本写法,他的那篇文章描述的略微有点啰嗦&#xff0…

2016 7 25 链表

1 #include<stdio.h>2 #include<stdlib.h>3 /* 4 usingnamespacestd;5 6 structNode7 {8 int data;//数据域9 struct Node*next;//指针域10 };11 12 /*13 Create14 *函数功能&#xff1a;创建链表.15 *输入&#xff1a;各节点的data16 *返回值&#xff1a;指…

php数值操作,php数值计算num类简单操作示例

php数值计算num类简单操作示例,在线,计算器,小数,整数,程序设计php数值计算num类简单操作示例易采站长站&#xff0c;站长之家为您整理了php数值计算num类简单操作示例的相关内容。本文实例讲述了php数值计算num类简单操作。分享给大家供大家参考&#xff0c;具体如下&#xff…

YAML-学习笔记!

YAML学习笔记 一、YAML简介 YAML&#xff0c;即YAML Ain’t Markup Language的缩写&#xff0c;YAML 是一种简洁的非标记语言。YAML以数据为中心&#xff0c;使用空白&#xff0c;缩进&#xff0c;分行组织数据&#xff0c;从而使得表示更加简洁易读。 二、YAML语法 1、基本规…

CentOS远程监控

近日&#xff0c;因工作需要&#xff0c;学习了CentOS远程监控的水平有限&#xff0c;多指教。 远程访问CentOS&#xff0c;包括三种方式ssh&#xff0c;telnet&#xff0c;vnc。 本例涉及的是以vnc远程访问CentOS。指令在root下操作。注意&#xff1a;vnc的端口为5900&#xf…

aix oracle 10.2.0.1 升级 10.2.0.4,AIX Oracle RAC 升级到10.2.0.4.0要特别注意的问题 - 爱肯的专栏 ......

AIX Oracle RAC 升级到10.2.0.4.0过程有如下报错(直接升级到10.2.0.4不需要应用Patch:6160398)&#xff1a;rootbwgl_db2:/u01/app/oracle/crs_1/bin# /u01/app/oracle/crs_1/install/root102.shError : Please change the CRS_ORACLE_USER id to have the following OS capabi…

将文件提交到github的两种方法

方法一 简要步骤如下&#xff1a; 登陆github&#xff0c;创建git仓库。记此git仓库的地址为[github_repository_url]&#xff0c;例如git仓库的地址&#xff1a;https://github.com/galian123/nodejs_http_server 在本地的工程目录执行git init&#xff0c;此工程目录是要提…

Visual Studio 2017新版发布,极大提高开发效率丨附下载

最新的Visual Studio 2017免费下载&#xff1a;https://www.evget.com/product...【包含Professional、Enterprise、Community版本】 为任何开发、应用和平台提供无与伦比的效率&#xff0c;Visual Studio 2017 候选发布。 提高了效率 代码导航、IntelliSense、重构、代码修复和…

BGP路由协议详解(完整篇)

原文链接&#xff1a;http://xuanbo.blog.51cto.com/499334/465596/ 2010-12-27 12:02:45 上个月我写一篇关于BGP协议的博文&#xff0c;曾许诺过要完善这个文档&#xff0c;但因最近的工作和授课很忙&#xff0c;所以没有时间进行完善。为了实现这个承诺&#xff0c;我在去外…

oracle 备份导出,oracle 怎么备份或导入导出表

exp/imp下面介绍的是导入导出的实例&#xff0c;向导入导出看实例基本上就可以完成&#xff0c;因为导入导出很简单。数据导出&#xff1a;1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中exp system/managerTEST filed:\daochu.dmp fully2 将数据库中…

GitHub+Hexo搭建自己的Blog之-本地环境部署01

前言 之前我的博客没有绑自己的域名&#xff0c;一直在github上放着&#xff0c;访问起来比较麻烦&#xff0c;前阵子在阿里云买了这个域名&#xff0c;配置上之后&#xff0c;就可以通过自己的域名访问了&#xff0c;有些朋友问我这个博客怎么搭的&#xff0c;用的什么主题&am…

appsettings 连接oracle数据库,ABP .net core集成访问Oracle数据库

1.添加包引用&#xff1a;Microsoft.EntityFrameworkCore.RelationalOracle.EntityFrameworkCore2.重写DbContext OnModelCreating/// /// 判断如果是Oracle&#xff0c;需要执行Schema/// /// protected override void OnModelCreating(ModelBuilder modelBuilder){//判断当前…

Day08-函数(3)

import functools #偏函数 def demo(a,b,c,d):print(a,b,c,d)# def partital_demo(a,b): # demo(a,b,3,4) # partital_demo(1,2)#实现偏函数 # #固定前两个 # demo functools.partial(demo,5,6) # demo(10,50)# #固定后两个 # demofunctools.partial(demo,c3,d5) # demo(1…

使用VS2010编译Qt 5.6.1过程记录

由于Qt官方发布的Qt 5.6.1二进制安装包没有对应VS2010版本的&#xff0c;而我的电脑上只安装了VS2010&#xff0c;因此只能自己编译。 本文记录本人的编译安装过程&#xff0c;以及其中遇到的一些问题。 本文使用VS2010 32位编译Qt 5.6.1。 1. 下载Qt源代码 Qt源代码下载地址&…

golang 指针

指针1、简单的定义一个指针package mainimport "fmt"func main(){var p *inti :2p &ifmt.Println("memory address i:",p) } //执行结果&#xff1a; memory address i: 0xc42000a2e02、打印指针的值package mainimport "fmt"func main(){v…

php防错处理,更好的PHP错误处理

错误类型PHP 主要有两种错误&#xff1a;触发错误和异常。其中触发错误大概可以分为&#xff1a;编译错误、引擎错误和运行时错误&#xff0c;其中前两个是无法捕获的&#xff1b;异常都是可以捕获的&#xff0c;当没有尝试捕获时则会中断代码。触发错误可以通过 error_get_las…

Windows安装Apache注册服务出现(OS 5)拒绝访问。 : AH00369: Failed to open the Windows service manager,

windows安装Apache&#xff0c;注册服务出现“(OS 5)拒绝访问。 : AH00369: Failed to open the WinNT service manager..."错误 在安装Apache的时候&#xff0c;我下载的是zip格式&#xff0c;不是msi安装版&#xff0c;需要自己注册服务&#xff0c;才能在桌面任务栏里有…