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());

来表示二者的绑定关系。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 粘包问题怎么解决_包带粘手怎么处理

    粘包问题怎么解决_包带粘手怎么处理如何解决粘包问题粘包就是连续向对端发送两个或者两个以上的数据包,对端在一次收取中受到的数据包数量可能大于1个,当大于1个时,可能时几个包加上某个包的部分,这这干脆几个完整的包在一起。当然,也可能收到的数据只是一个包的部分,这种情况一般也叫做半包。无论是半包问题还是粘包问题,因为TCP是流式数据,所以其解决思路还是从收到的数据中把包与包的边界区分出来。如何区分,有以下三种办法。固定包长的数据包。固定包长,即每个协议包的长度都是固定的。假如我们规定每个协议包的大小都是64字节,每收满64字节,就取出来

    2022年8月11日
    9
  • mysql5.7 分区表_mysql分区表学习

    mysql5.7 分区表_mysql分区表学习一:怎样对已有数据的表进行表分区可以直接altertable进行修改。如:USEdba;ALTERTABLEt3PARTITIONBYRANGE(id)(PARTITIONp1VALUESLESSTHAN(5),PARTITIONp2VALUESLESSTHAN(10),PARTITIONp3VALUESLESSTHANmaxvalue);二:分区表的限制2…

    2022年5月11日
    63
  • Cacti插件详解之——Weathermap(1)

    Cacti插件详解之——Weathermap(1)

    2021年8月28日
    142
  • 08【Verilog实战】4bit移位寄存器设计与功能验证(附源码)[通俗易懂]

    08【Verilog实战】4bit移位寄存器设计与功能验证(附源码)[通俗易懂]一、Overview(1)Theory(2)Demand二、Interface三、Timeing四、DesignandFunctionalVerification(1)RTL(2)TestBench五、Result(1)行为级描述测试结果(2)结构级描述测试结果

    2022年7月16日
    16
  • Flashfxpv.3.5.4注册码

    Flashfxpv.3.5.4注册码在安装好任意版本的Flashfxp之后,只要在注册栏中,全盘粘贴一下文字就可以了^_^——–FlashFXPRegistrationDataSTART——–FLASHFXPwQAOlhkgwQAAAAC6W5MNJwTnsl73nIraAU149tnCQS0hmZU3GGBQG1FtoSp5x0mUgA7bFW0qr0fKk2KCA+v2CCrFbF+q

    2022年7月26日
    17
  • vmware虚拟机安装windows10_虚拟机15安装教程win7

    vmware虚拟机安装windows10_虚拟机15安装教程win71.去下载win7原装镜像,推荐去官方网站下载:https://msdn.itellyou.cn/2.这里注意一点,防止下载的镜像可能出现差错,我们使用iHasher检验一下完整性,确定SHA1值跟我们下载的那个SHA1值一样就行3.打开vmware虚拟机,新建虚拟机4.这里我们选择自定义5.兼容性自己选择,可以向下兼容,点击下一步6.选择win7镜像,这里我们选稍后安装操作系统(…

    2022年9月28日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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