2010-07-14 55 views
2

我知道ModelBinder是一個很好的地方可以處理請求,這樣您就可以將這種類型的代碼保留在控制器之外。使用表單值將是一個例子。這似乎是有道理的,但是,我繼承了一個使用自定義活頁夾的應用程序,我似乎無法弄清楚它是如何工作的或爲什麼工作的。我不是在MVC中「獲取」ModelBinder 2

粘合劑本身的存在是爲了對付他們(時區)的應用程序中使用,因此它在Application_Start方法進行註冊,在全球,像這樣只的TimeZoneInfo對象:

binders.Add(new System.Collections.Generic.KeyValuePair<Type, IModelBinder>(typeof(TimeZoneInfo), new TimeZoneInfoModelBinder())); 

其中粘合劑是鍵入ModelBinderDictionary。該粘合劑本身則是這樣的:

public class TimeZoneInfoModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 
     string tzId = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue; 


     try 
     { 
      return TimeZoneInfo.FindSystemTimeZoneById(tzId); 
     } 
     catch (Exception ex) 
     { 
      bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex); 
     } 
     return null; 
    } 
} 

現在從單步調試代碼我知道當我POST數據回涉及其上有一個的TimeZoneInfo屬性的特定型號的服務器此Binder只調用。我的假設是:

  • 運行時「知道」所有的模型,只調用自定義粘結劑時,它會發現相同的類型在該粘結劑通過一個屬性。
  • 這個正在做的原因是因爲所述的TimeZoneInfo類型是一個複雜的類型,因此,不能隱從字符串轉換爲(POST數據)

這是這個特定的正確認識實例還是我錯過了什麼?

謝謝!

回答

1

你靠近...

模型綁定認爲所有來自請求的表單數據,URL查詢字符串,和路由參數數據。活頁夾將嘗試綁定到action方法的參數以及同時定義了get和set的模型的任何公共屬性。這是通過考慮參數和/或公共屬性的名稱來完成的。

由於所有輸入源都是名稱值格式,所以名稱是匹配的。例如,如果有一個「id」路由參數,並且您的操作方法在其簽名中具有「id」參數,則綁定器會將路由參數綁定到該操作方法參數。如果國家/地區表單域和具有公共國家/地區屬性的模型,則模型聯編程序將嘗試將表單域綁定到模型。等

活頁夾考慮綁定時的屬性的類型。默認的模型綁定器知道如何綁定到標量屬性(int,decimal,DateTime等)。它還可以綁定到一個列表(鍵格式MyList [0])或一個複雜類型,該類型又會暴露子屬性(例如,鍵格式Rectangle.Width)。

您發佈的示例添加了綁定到TimeZoneInfo對象的功能。由於表單參數,查詢參數或路由參數的名稱與您的模型上的公共屬性的名稱相匹配,因此該綁定器將被調用,從而公開一個返回TimeZoneInfo對象的getter和setter。

注意ModelBinder與ModelState字典配合使用。即使無法將用戶輸入無法轉換爲目標類型,也必須保留無效的用戶輸入。在這種情況下,將向ModelState字典添加一個錯誤,並保留輸入參數的原始值,以便將其包含在帶有驗證錯誤的表單的重新渲染中。

+0

感謝您的解釋羅布。 – dparsons 2010-07-20 17:06:37

相關問題