Controller代码如下:
//
// GET: /Home/
[HttpGet, ImportModelStateFromTempData]
public ActionResult Register()
{
return View();
}
[HttpPost, ExportModelStateToTempData]
public ActionResult RegisterProcess(Models.RegisterModel registerModel)
{
if (ModelState.IsValid)
{
return RedirectToAction("RegisterSuccess");
}
return RedirectToAction("Register");
}
[HttpGet]
public ActionResult RegisterSuccess()
{
return View();
}
上面的ImportModelStateFromTempData和ExportModelStateToTempData是ActionFilter
是为了解决Redirect不能保存Model的验证错误的问题.
实现的基本原理是通过ExportModelStateToTempData把Model的验证错误存放到TempData中,
通过ImportModelStateFromTempData从TempData中把验证错误导入.
View代码是:
@using (Html.BeginForm("RegisterProcess", "Home"))
{
<fieldset>
<legend>Register</legend>
@Html.ValidationSummary(true)
<ol>
<li>
@Html.LabelFor(m => m.NickName)
@Html.TextBoxFor(m => m.NickName)
@Html.ValidationMessageFor(m => m.NickName)
</li>
<li>
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)
</li>
</ol>
<input type="submit" value="Sumbit" />
</fieldset>
}
ImportModelStateFromTempData和ExportModelStateToTempData的实现代码如下:
using System.Web.Mvc;
namespace MVCFormValiation.Filters
{
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute
{
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}
public class ExportModelStateToTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//Only export when ModelState is not valid
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
//Export if we are redirecting
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}
base.OnActionExecuted(filterContext);
}
}
public class ImportModelStateFromTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
if (modelState != null)
{
//Only Import if we are viewing
if (filterContext.Result is ViewResult)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
else
{
//Otherwise remove it.
filterContext.Controller.TempData.Remove(Key);
}
}
base.OnActionExecuted(filterContext);
}
}
}