本文的环境是Asp.net Mvc Codeplex Preview 5

前文提到我们可以使用 Controller中的UpdateModel来获取 繁杂类型

例如

1 UpdateModel(x, Request.Form.AllKeys);

但是这里有些问题,当我们使用Request.Form.AllKeys时,提交的数据中有非x属性时,就会发生错误:

The model of type 'MyModel' does not have a property named 'Name2'.

但是使用

1 UpdateModel(x, new[] {"IDX", "Name"});

这种形式,我们又会觉得它太过麻烦。

其实Asp.net Mvc为我们提供了一种很简单的传递复杂数据的方式,它类似于Monorail中的DataBinder:

我们完全可以通过以下方式来传递数据。例如

view:

1     <%using (Html.Form("home", "about", FormMethod.Post)) {%>
2     <%=Html.TextBox("my.ID")%>
3     <%=Html.TextBox("my.Name")%>
4     <%=Html.SubmitButton()%>
5     <%} %>

controller:

        [AcceptVerbs("post")]
        public ActionResult About([ModelBinder(typeof(MyModelBinder))]MyModel my) {
            ViewData["Title"] =my.Name + my.ID;
            return View();
        }

这样我们就可以从my中获取到Post过来的值了,这里的关键在于[ModelBinder(typeof(MyModelBinder))]

而 MyModelBinder的实现方法如下

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Globalization;
 5 using System.Linq;
 6 using System.Web.Mvc;
 7 
 8 /// <summary>
 9 /// 这个类是根据Controller.UpdateModel方法更改而成
10 /// </summary>
11 public class MyModelBinder : IModelBinder{
12     #region IModelBinder 成员
13 
14     public object GetValue(ControllerContext controllerContext, string modelName, Type modelType,
15                            ModelStateDictionary modelState){
16         object model = Activator.CreateInstance(modelType); //将做为参数的类实例化了
17         IEnumerable<string> keys = modelType.GetProperties().Select(c => c.Name); //得到该对象的属性的名的字符串数组,这里的结果应该为["ID","Name"]
18         string objectPrefix = modelName; //这个就是,我的对象名叫my则会检查  name="my.ID" name="my.Name"的表单字段
19 
20         PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(model); //对象的属性的集合
21         var dictionary = new Dictionary<string, PropertyDescriptor>();
22         foreach (string str in keys){
23 //遍历属性的字符串集合即["ID","Name"]
24             if (!string.IsNullOrEmpty(str)){
25                 PropertyDescriptor descriptor = properties.Find(str, true);
26                 if (descriptor == null){
27                     throw new ArgumentException(
28                         string.Format(CultureInfo.CurrentUICulture, "无此属性{0},{1}", new object[]{model.GetType().FullName, str}),
29                         "modelName");
30                 }
31                 string str3 = string.IsNullOrEmpty(objectPrefix) ? str : (objectPrefix + "." + str); //将对象名与属性名拼接,如my.ID
32                 dictionary[str3] = descriptor;
33             }
34         }
35         foreach (var pair in dictionary){
36             string key = pair.Key;
37             PropertyDescriptor descriptor2 = pair.Value;
38             object obj2 = ModelBinders.GetBinder(descriptor2.PropertyType).GetValue(controllerContext, key,
39                                                                                     descriptor2.PropertyType, modelState);
40             if (obj2 != null){
41                 try{
42                     descriptor2.SetValue(model, obj2); //设置属性的值
43                     continue;
44                 }
45                 catch{
46                     //如果有使用验证Helepr则会显示在Html.ValidationSummary中
47                     string errorMessage = string.Format(CultureInfo.CurrentCulture, "验证失败{0}:{1}", new[]{obj2, descriptor2.Name});
48                     string attemptedValue = Convert.ToString(obj2, CultureInfo.CurrentCulture);
49                     modelState.AddModelError(key, attemptedValue, errorMessage);
50                     continue;
51                 }
52             }
53         }
54         return model; //最后 返回这个我们设置完属性的对象
55     }
56 
57     #endregion
58 }

这样我们就实现了 用Action的参数传递复杂类型。

当然,如果你连[ModelBinder(typeof(MyModelBinder))]都不想写了,想直接来以下写法,

1         [AcceptVerbs("post")]
2         public ActionResult About(MyModel my) {
3             ViewData["Title"] =my.Name + my.ID;
4             return View();
5         }

这个也是可以的不过你要在Application_Start中添加

ModelBinders.Binders.Add(typeof (MyModel), new MyModelBinder());

来表示二者的绑定关系。

多谢Leven's Blog、lulu Studio

示例程序下载http://files.cnblogs.com/chsword/MyModelBinder.rar

转载于:https://www.cnblogs.com/cxd4321/archive/2009/09/16/1567904.html

Asp.net Mvc Codeplex Preview 5 第三篇 实现Action参数传递繁杂类型 【转】相关推荐

  1. ASP.NET MVC V2 Preview 1 发布 期望VS有更好的表现

    ASP.NET MVC V2 Preview 1官方首页:http://aspnet.codeplex.com/ 在这里可以下载 以下是网友的转载,介绍的还是比较详细的: 预览版是在.NET 3.5 ...

  2. 《精通 ASP.NET MVC 3 框架(第三版)》----第2章 准备工作 2.1 准备工作站

    本节书摘来自异步社区<精通 ASP.NET MVC 3 框架(第三版)>一书中的第2章,第1节,作者: [美]Adam Freeman , Steven Standerson,译者: 林逸 ...

  3. ASP.NET MVC URL重写与优化(初级篇)-使用Global路由表定制URL

    ASP.NET MVC URL重写与优化(初级篇)-使用Global路由表定制URL 引言--- 在现今搜索引擎制霸天下的时代,我们不得不做一些东西来讨好爬虫,进而提示网站的排名来博得一个看得过去的流 ...

  4. 在ASP.NET MVC 中获取当前URL、controller、action

    在ASP.NET MVC 中获取当前URL.controller.action URL的获取很简单,ASP.NET通用: [1]获取 完整url  (协议名+域名+虚拟目录名+文件名+参数) stri ...

  5. ASP.NET MVC下使用AngularJs语言(三):ng-options

    今天使用angularjs的ng-options实现一个DropDownList下拉列表. 准备ASP.NET MVC的model: public class MobilePhone{public i ...

  6. 《从零开始学习ASP.NET MVC 1.0》-开天辟地入门篇

    <从零开始学习ASP.NET MVC 1.0> 文章导航 (一) 开天辟地入门篇 (二) 识别URL的Routing组件 (三) Controller/Action 深入解析与应用实例 ( ...

  7. ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL(转)

    http://www.cnblogs.com/John-Connor/archive/2012/05/03/2478821.html 引言-- 在初级篇中,我们介绍了如何利用基于ASP.NET MVC ...

  8. 学习 ASP.NET MVC (第二回)实战篇

    上篇简单的了解了ASP.NET MVC的基本概念和基本流程,接下来的几篇将通过简单的实例,来看看如何通过ASP.NET MVC创建应用程序.Demo很简单也很基础,高手绕过.   闲话少说,直接进入正 ...

  9. [转载]ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL

    引言-- 在初级篇中,我们介绍了如何利用基于ASP.NET MVC的Web程序中的Global文件来简单的重写路由.也介绍了它本身的局限性-依赖于路由信息中的键值对: 如果键值对中没有的值,我们无法将 ...

最新文章

  1. 衡量计算机的平均无故障时间6,平均无故障时间MTBF测试及计算过程
  2. linux 编译 编解码
  3. spring boot 及微服务 学习笔记
  4. SQLServer优化:SQLServer中NOLOCK关键字的用法介绍
  5. 怎么使用7zip进行分批压缩_怎么使用钢结构抛丸机对钢结构进行除锈?
  6. centos mysql.tar.gz_centos7.2 mysql tar.gz 搭建 (亲测成功)
  7. 泊松分酒 java课件_泊松分酒原理 - 我类个擦的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. bootstrap 输入错误提示_win7系统提示explorer.exe应用程序错误怎么办
  9. asp控制oracle,asp下用OracleInProcServer完成对Oracle的连接和操作
  10. 沈阳计算机考试都学什么,沈阳计算机考研考什么科目
  11. 【Spring】HttpMessageConverter的作用及替换
  12. 解决微信小程序要求TLS版本不低于1.2问题
  13. 如何用UE4制作2D游戏文档(四)——NPC篇
  14. 昆仑通态触摸屏如何把参数由触摸屏传递到PLC_S71200与其他PLC/组态软件无线串口通讯(自由口)...
  15. 2022-2028全球汽车后置摄像头模组行业调研及趋势分析报告
  16. 《软件项目管理》课程知识总结
  17. 关注点分离(Separation of concerns, SoC)
  18. bzoj 2959: 长跑
  19. ArcGIS超级工具目录
  20. 关于二代测序中duplication产生和占比问题的探讨

热门文章

  1. 【深度学习入门到精通系列】神经网络中动量的概念
  2. python getcwd 与dirname_python慎用os.getcwd() ,除非你知道【文件路径与当前工作路径的区别】...
  3. python统计个数的函数_Python
  4. cwntos新建目录挂载磁盘_centos挂载磁盘及扩展根目录
  5. delphi 获取4位的年份_原来华为手机拨号键盘这么厉害!除了能打电话,还有4个隐藏功能...
  6. 网络营销外包——网络营销外包前关键词排名反超首页的原因在哪里
  7. mysql从表中转移数据文件_MySQL 数据文件迁移找不到表
  8. python 协程_Python 协程与 Go 协程的区别(一)
  9. swoole 要求php版本,swoole哪个版本支持php5
  10. 虚拟化服务器端口用万兆,万兆以太网部署需要注意的方面有哪些