2010-04-05 63 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