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

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

本文的环境是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());

来表示二者的绑定关系。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110860.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mac navicate 15激活码【2021免费激活】

    (mac navicate 15激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

  • docker(6)镜像的使用「建议收藏」

    docker(6)镜像的使用「建议收藏」前言Docker的三大核心概念:镜像、容器、仓库。初学者对镜像和容器往往分不清楚,学过面向对象的应该知道类和实例,这跟面向对象里面的概念很相似我们可以把镜像看作类,把容器看作类实例化后的对象。|

  • stm32蓝牙模块控制小车_如何让电脑有蓝牙功能

    stm32蓝牙模块控制小车_如何让电脑有蓝牙功能重要声明看过我前面51小车博客的都知道我是软件工程专业的,对于硬件方面都是因为感兴趣自学的,这不,因为今年寒假放假比较早,趁这个时间学习了STM32相关知识,经过近一个月的学习对于STM32算是入门了,为了检验自己的学习效果,我决定就着51小车的架子用STM32试试,经过一个下午的忙活算是成功了!!!所以再来和大家分享一下。所需知识贮备相信看到这篇文章的小伙伴都是有相关基础的,这里只是给和我一样自学的小伙伴提个醒。动手之前你需要这些:硬件电路连接相关能力C语言基础能力STM32定时器、中断、串

  • centos7系统更新命令_centos 更新

    centos7系统更新命令_centos 更新1.查看网络IP ifconfig2.下载命令 wget+网址3.安装 yum-y install + 目标4.删除文件 sudo rm 文件所在目录/目标强制删除文件 rm -f删除目录 rm -rf5.复制一个文件到另一个文件夹sudo cp /文件夹/文件 /另一个文件夹6.对一些文件进行读写sudo vim 文件名7….

  • crontab 打开GUI

    crontab 打开GUI

  • 黄金k线图基础知识图解

    黄金k线图基础知识图解  黄金可以说是2019下半年最热门的投资品种,如果懂得选择像现货黄金这样但杠杆型产品,收益更是如虎添翼。但如果你只是刚开始进入这个市场的投资者,最好从黄金k线图基础知识图解开始,认证学习关于K线和交易的知识,才能掌握在黄金市场致富的密码。  一、黄金K线分类图解  1、如果按开、收盘价的关系,可分为阳线、阴线和同价线(十字线、T字线、一字线)。  2、如果按实体的大小,可分为大阳(阴)线、中阳(阴)线和小阳(阴)线。  3、如按影线的有无,可以分为光头K线、光脚K线、光头光脚K线和带有上下影的K线

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号