Asp.net Mvc Codeplex Preview 5 第三篇 实现Action参数传递繁杂类型

简介: 本文的环境是Asp.net Mvc Codeplex Preview 5   前文提到我们可以使用 Controller中的UpdateModel来获取 繁杂类型 例如 1 UpdateModel(x, Request.

本文的环境是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 Bloglulu Studio

 

 

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

 

目录
打赏
0
0
0
0
1
分享
相关文章
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
84 7
|
7月前
|
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
203 7
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
123 0
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
87 0
|
7月前
|
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
195 0
.NET Core 和 .NET 标准类库项目类型有什么区别?
在 Visual Studio 中,可创建三种类库:.NET Framework、.NET Standard 和 .NET Core。.NET Standard 是规范,确保跨.NET实现的API一致性,适用于代码共享。.NET Framework 用于特定技术,如旧版支持。.NET Core 库允许访问更多API但限制兼容性。选择取决于兼容性和所需API:需要广泛兼容性时用.NET Standard,需要更多API时用.NET Core。.NET Standard 替代了 PCL,促进多平台共享代码。
|
10月前
|
C#.Net筑基-类型系统②常见类型--枚举Enum
枚举(enum)是C#中的一种值类型,用于创建一组命名的整数常量。它们基于整数类型(如int、byte等),默认为int。枚举成员可指定值,未指定则从0开始自动递增。默认值为0。枚举可以与整数类型互相转换,并可通过`[Flags]`特性表示位域,支持位操作,用于多选场景。`System.Enum`类提供了如`HasFlag`、`GetName`等方法进行枚举操作。
106 7
C#.Net筑基-类型系统②常见类型 --record是什么类型?
`record`在C#中是一种创建简单、只读数据结构的方式,常用于轻量级数据传输。它本质上是类(默认)或结构体的快捷形式,包含自动生成的属性、`Equals`、`ToString`、解构赋值等方法。记录类型可以继承其他record或接口,但不继承普通类。支持使用`with`语句创建副本。例如,`public record User(string Name, int Age)`会被编译为包含属性、相等比较和`ToString()`等方法的类。记录类型提供了解构赋值和自定义实现,如密封的`sealed`记录,防止子类重写。