2009-04-24 24 views
2

比方說,你有簡單的對象是這樣的:爲什麼默認模型聯編程序不在表單數據中時驗證字段?

public class MyObject { 
    public int Test { get; set; } 
} 

你指望默認的模型綁定,以確保發佈象下面這樣的形式,當用戶不離開「測試」字段爲空:

<form method="post" action="/test"> 
    <p> 
     <%=Html.TextBox("Test") %> 
     <%=Html.ValidationMessage("Test") %> 
    </p> 
    <input id="Submit1" type="submit" value="submit" /> 
</form> 

,因此這個動作:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Test(MyObject o) { 
    return View(); 
} 

這一切時,表單數據包含了「測試」的主要預期作品(如「Test=val「或」Test=「)

但是,如果密鑰不在表單數據中,則驗證不會發生。因此,如果發送空白的請求或使用像AnotherField=foo這樣的數據的請求,則模型對象上的屬性默認爲該類型的默認值(在此情況下爲0)。並且ModelState.IsValid返回true。

這就是IMO,而不是人們所期望的行爲。
那麼你有什麼建議改變這種行爲?

編輯: 請記住,惡意用戶可以只篡改表單數據很容易與FireBugTamper Data插件通過默認的模型綁定的驗證,這可能會導致一些安全問題。

回答

1

您可能會考慮使用xVal來執行必要的客戶端和服務器端驗證組合。有了它,你可以添加一個屬性到你的測試屬性,指定什麼類型的驗證規則(必需的,正則表達式驗證等)適用於它,然後再做一些工作,讓它爲你生成JavaScript規則以及很容易執行模型驗證。

您已經意識到您違反了開發規則 - 絕不相信客戶端輸入。真的沒有辦法繞過它。

客戶端驗證(防止往返發現有錯誤)是很好的,服務器端驗證驗證事情真正按順序是必須的。

+0

實際上,我試圖解釋的問題與計算客戶端驗證有點不同。我用DataAnnotationsModelBinder做了同樣的測試,得到了同樣的結果。問題是如果該字段不在表單數據中,驗證不會發生。 DataAnnotationsModelBinder:http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html 我也來看看xVal。感謝您的迴應。 – 2009-04-24 12:52:18

+0

爲了做你想做的事情,你需要一些方法來驗證表單值是否提供給表單中的所有字段。有沒有超級簡單的方法來自動做到這一點,我可以想到我的頭頂... – 2009-04-24 16:32:03

0

我希望它的設計,因爲我即將開始依靠這種行爲!

在一個實例我有兩個控制這回發以下字段:

ShippingAddress.FirstName 
ShippingAddress.LastName 
ShippingAddress.Line1 
ShippingAddress.Line2 

BillingAddress.Email 
BillingAddress.FirstName 
BillingAddress.LastName 
BillingAddress.Line1 
BillingAddress.Line2 

注:帳單地址沒有電子郵件顯示,即使課程的基本模型仍然有它

如果在我的模型中,我將電子郵件作爲[必填]數據註釋,然後僅在帳單地址中缺少時纔會投訴。

但我絕對看到你的觀點!我只是在這裏依靠這個場景!

+0

似乎仍然是行爲 – 2010-01-17 03:44:56

0

在研究了將表單值傳入我的控制器方法的所有不同方法之後,我發現「最安全」是將每個表單域明確定義爲控制器的參數。副作用是如果一個表單沒有其中一個字段,它會拋出一個異常 - 這將解決你的問題。

2

不幸的是,它沒有通過設計驗證字段。請看看我發現和評論的Codeplex issue

真的很不幸,MS已經決定這是他們模型活頁夾的正確行爲。

我相信默認的模型聯編程序應驗證整個實體而不僅僅是發佈的數據。

相關問題