程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> Asp.net Mvc Codeplex Preview 5 第三篇 實現Action參數傳遞繁雜類型

Asp.net Mvc Codeplex Preview 5 第三篇 實現Action參數傳遞繁雜類型

編輯:關於ASP.NET

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

來表示二者的綁定關系。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved