ASP.NET MVC保持表单数据状态的方法:input辅助器+模型绑定

本文介绍了ASP.NET MVC如何在不使用ViewState的情况下保持表单数据状态。当表单验证失败需要重新显示时,利用input辅助器结合模型绑定能实现这一目标。关键点在于视图使用Html.Editor等辅助器,且控制器方法中进行模型绑定。如果模型绑定后清空ViewData,表单将显示为空。此外,未参与绑定的字段会恢复其初始值。

        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的属性值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值