ASP.NET使用ViewState保持网页的状态,服务器端控件也默认使用该对象保持状态。该技术的主要弊端是服务器需要发送大量的状态数据给客户端。ASP.NET MVC没有采用服务器端控件技术,也就不需要ViewState了。那么,如何保证提交的网页表单数据再次呈现呢。例如一种常见情况是:提交网页后没有通过数据验证,此时需要在原数据的基础上再次修改,于是需要再呈现原网页的表单数据。当然,有多种技术方法可以实现该目的。但ASP.NET MVC提供了一个更简单和直接的方法,即:在视图中使用input辅助器+控制器方法中模型绑定。
以下是默认的Home+Index控制器及其方法代码。
using System.Web.Mvc;
using System.Web.ModelBinding;
namespace Test.Controllers
{
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index() // 呈现一个空表单数据的网页
{
return View(new Person());
}
[HttpPost]
public ActionResult Index([Form] Person person) // 再次呈现提交的表单数据
{
return View(); // 如果 return View(person)则使用模型属性值,该值与ViewData可能不同。例如PersonId输入abc时,绑定后的PersonId为0.
}
}
}
对应试图如下。
@model Test.Controllers.Person
@using (Html.BeginForm())
{
<p><label>PersonId:</label>@Html.TextBox("PersonId")</p>
<p><label>Name:</label>@Html.EditorFor(x=>x.Name)</p>
<input type="submit" value="Submit" />
} 测试(VS2012+.NET Framework 4.5+MVC4)表明,无论在网页的表单中录入啥数据,提交后仍然呈现原数据。
需要注意如下几点:
- 视图必须使用input辅助器,例如:Html.Editor、Html.EditorFor、Html.TextBox等。不能使用HTML元素形式,例如:<input type="text" name="PersonId" value="0" />。
- 必须在控制器方法中做一次模型绑定操作,例如代码中的自动绑定表单Index([Form]Person person)。显然,这里使用了默认的模型绑定器。也可以使用UpdateModel或TryUpdateModel做模型绑定。显然,就是这个绑定动作给ViewData赋了相关字段的值(可以测试:在模型绑定后和return View()前,添加语句ViewData.Clear(),此时将呈现空数据的表单)。
- 对一般字段(即非类型字段),同样可以做到状态保持。此时方法参数可能为 Index(int personId, string name)等的绑定形式。
- 如果某个字段没有参与绑定,那么该字段在呈现时将恢复初始值。例如:字符串初始值为空,整数初始值为0,等等。这个可以理解为:没有参与绑定,则ViewData()中没有该字段的值,也就不会呈现该值。
Jon Galloway在《ASP.NET MVC4高级编程(第4版)》中指出,表单中的input辅助器方法使用了ViewData的同名字段的值(例如Name属性值)渲染网页。根据笔者的代码和测试,如果试图模型@model为空(null),则input辅助器使用ViewData的同名字段的值;如果@model非空,则input辅助器使用@model的属性值。
本文介绍了ASP.NET MVC如何在不使用ViewState的情况下保持表单数据状态。当表单验证失败需要重新显示时,利用input辅助器结合模型绑定能实现这一目标。关键点在于视图使用Html.Editor等辅助器,且控制器方法中进行模型绑定。如果模型绑定后清空ViewData,表单将显示为空。此外,未参与绑定的字段会恢复其初始值。

1309

被折叠的 条评论
为什么被折叠?



