2010-04-05 62 views
6

這是工作,但如何?asp.net MVC如何在回發中記住我的錯誤值?

我有一個職位控制器動作:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Person person) 
{ 
    bool isvalid = ModelState.IsValid; 
    etc. 

Person對象有一個屬性生日,DateTime類型。 當我在表單中輸入一些無效數據時,比如說'blabla'這顯然不是一個有效的日期時間,它將使用正確的數據填充所有(其他)Person屬性,並使用新的空白DateTime填充BirthDate屬性。 bool無效的值爲'false'。 目前爲止這麼好。

那麼我這樣做:

return View(p); 

,並在視圖中我有這樣的:

<%= Html.TextBox("BirthDate", String.Format("{0:g}", Model.BirthDate)) %> 
<%= Html.ValidationMessage("BirthDate", "*") %> 

螞蟻有說到:我的預期模型包含新的,空白的日期時間,因爲我沒有不會放入任何新數據。其次,當視圖顯示某些內容時,它必須是DateTime,因爲Model.BirthDate不能包含除DateTime之外的任何內容。 但令我驚訝的是,它顯示了'blabla'值的文本框! (以及它後面的紅色*)

哪個課程很好,因爲用戶可以看到他輸入的內容是錯誤的,但是如何將該(blabla)字符串傳送到日期時間字段中的視圖?編輯: ModelState信息在這裏幫了我很多。 我還注意到,在MVC 2中,當您爲 Html.EditorFor() 創建自己的模板時,您必須自己實現此行爲。 我創建了一個

DateTime.ascx 
在/視圖/共享/ EditorTemplates文件夾

,並在那裏我不得不檢查,如果有此屬性值的ModelState錯誤,如果是這樣,展現在代替無效數據模型數據。

所以在視圖中我用這個:

<%= Html.LabelFor(model => model.DateOfBirth) %> 

,並在DateTime.ascx我用這個:

<% 
bool invalidData = false; 
string propertyName = ViewData.ModelMetadata.PropertyName; 

ModelState ms = ViewData.ModelState[propertyName]; 
if (ms != null) 
{ 
    invalidData = ms.Errors.Count > 0; 
} 
string valueToshow = invalidData ? ViewData.ModelState[propertyName].Value.AttemptedValue : String.Format("{0:g}", Model); 
%> 
<input class="text-box single-line" id="<%= propertyName %>" name="<%= propertyName %>" type="text" value="<%= valueToshow %>" /> 

回答

10

的ModelState舉行KeyValuePairs與該鍵爲字段名的每個表單元素價值就是你在現場投入的價值。然後Html Helpers在ModelState中查找,如果你沒有明確地指定一個值,他們將從ModelState中提取值。

+0

謝謝,現在沒有幫手做了更多的解析模型中的值。 – Michel 2010-04-05 21:20:35

4

先前輸入的值存儲在ModelState中。當你在表單上出現錯誤時,幫助器從ModelState中取出值,而不是使用Model中的值或專門提供的值(如果不提供顯式值,它將默認爲模型如果沒有錯誤時有值)。

+0

+1爲答案,基思是稍快,希望你不介意標記他的答案 – Michel 2010-04-05 21:19:52

+0

我認爲這個答案是正確的,基思的是不完全正確的。 Keith的答案指出,如果您沒有明確指定一個值,則使用ModelState;這個答案指出,如果出現錯誤,是否使用了ModelState,是否明確指定了值。當存在模型錯誤時,在POST控制器之後調用GET控制器的模式僅適用,因爲ModelState視圖數據總是覆蓋您在GET控制器中編碼的任何內容。 – 2013-12-02 16:43:40

1

我在'回發'中有一些代碼可以刪除無效的促銷代碼並將回覆大寫。即使您使用新值更新模型,它也不會顯示,因爲ModelState值優先(正如其他人已經回答的那樣)。

<%= Html.TextBox("PromoCode", Model.PromoCodes) %> 

但如果你有這個地方正在發生的情況下,你不想要的舊值持續,你需要做到這一點:

ModelState.Remove("PromoCode"); 

或明確設置的新值的ModelState(可能更好的方法):

ModelState.SetModelValue("PromoCode", 
     new ValueProviderResult(newValue, newValue, CultureInfo.CurrentCulture)); 
+0

+1。 – Michel 2010-04-06 07:21:19