让我们创建空的asp.net mvc 3应用程序。 代码是
namespace MvcApplication1.Controllers
{
public class MyModel
{
public int Id { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
return Index1(new MyModel() {Id = 100});
}
public ActionResult Index1(MyModel model)
{
var nm = new MyModel();
nm.Id = model.Id + 1;
return View("test", nm);
}
}
让我们创建名为test的共享视图。查看代码
@using MvcApplication1.Controllers
@model MyModel
@if (Model != null)
{
using (Html.BeginForm("Index1", "Home", FormMethod.Post, new { autocomplete = "off" }))
{
<div id="compareQuestions">
<p>@Model.Id</p>
@Html.HiddenFor(m => m.Id)
@Html.TextBoxFor(m => m.Id)
<input type="submit" value="save"/>
</div>
}
}
当我们第一次发布表单时一切正常,但是当它在文本框中的第一个帖子值之后重新加载时不正确。如果我们更改此值并在控制器上保存帖子,我们会得到具有不正确值的模型,但不会输入。这怎么可能?
答案 0 :(得分:2)
<p>@Model.Id</p>
和@Html.HiddenFor(m => m.Id)
之间存在显着差异。
当您发布表单时,所有POST的值都存储在ModelState
中
当您使用HtmlHelper
方法时,他们首先从ModelState
中提取值。如果ModelState
不包含值,则会查看实际的m.Id
。
因此,当您第一次获得表单时,没有ModelState
。但是,一旦您发布表单,它会将值存储到ModelState
,因此隐藏的输入使用该值而不是m.Id
。
如果您希望始终使用m.Id
,则需要清除控制器中的ModelState
:
public ActionResult Index1(MyModel model)
{
ModelState.Clear();
...
答案 1 :(得分:1)
看起来这是正确的行为,因为您已经编写了您的操作方法。在视图中,您要为同一个模型属性呈现文本框和隐藏字段。
因此,当您在帖子中将Id增加1时,您将在文本框中增加值并在隐藏字段中增加。
如果您希望文本框和隐藏字段在第二篇文章后具有不同的值,则您需要在模型上使用不同的属性。
另一个问题可能是,由于您有2个不同的<input
元素具有相同的名称,因此无法确定表单是否会从隐藏字段或文本框中发送值。同样,如果这两个字段应具有不同的值,则它们需要在模型上具有不同的属性。如果您希望它们始终具有相同的值,请在视图中放置TextBox或Hidden,但不能同时放置两者。