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)


相关推荐

  • linux修改密码命令passwd_linux重置系统到刚安装状态

    linux修改密码命令passwd_linux重置系统到刚安装状态新建Linux系统修改密码一、首先,打开VMwareWorkstation软件,在自己的界面打开虚拟机二、打开虚拟机后在如下界面单击鼠标左键使鼠标“消失”,按上下键使界面停留在如下所示,白条停留在第一行,再点击“e”键三、单击“e”键后进入如下界面,在linux…quiet这段代码后,initrd之前输入“rd.break”,再按ctrl+x启动进入下一个界面四、在以上界面中依次输入mount-oremount,rw/sysr

  • 零基础学Java(11)自定义类[通俗易懂]

    零基础学Java(11)自定义类[通俗易懂]前言之前的例子中,我们已经编写了一些简单的类。但是,那些类都只包含一个简单的main方法。现在来学习如何编写复杂应用程序所需要的那种主力类。通常这些类没有main方法,却有自己的实例字段和实例方法。

  • StringUtils.isBlank_StringBuilder

    StringUtils.isBlank_StringBuilderStringUtils.isNotBlank()

  • HTML meta refresh 刷新与跳转(重定向)页面

    HTML meta refresh 刷新与跳转(重定向)页面

  • 【阅读笔记】数据分析思维:分析方法和业务知识

    【阅读笔记】数据分析思维:分析方法和业务知识这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Mar

  • 识别引擎ocropy-&gt;ocropy2-&gt;OCRopus3总结

    论文:TheOCRopusOpenSourceOCRSystemTransferLearningforOCRopusModelTraining onEarlyPrintedBooksGitHub:https://github.com/tmbdev/ocropyhttps://github.com/tmbdev/ocropy2https://gith…

发表回复

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

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