MVC3 模型验证最佳实践在发布/状态更改后重定向 [英] MVC3 model validation best practice redirect after post / state change
问题描述
鉴于网络应用程序应始终在 POST(或任何不可重复的更改服务器端状态的请求)之后重定向......
Given that web apps should always redirect after a POST (or any non-repeatable request to change server-side state) ...
...人们如何使用 MVC3 模型验证和执行强制重定向?
... how are people using MVC3 Model Validation and performing the mandatory redirect?
推荐答案
通常你只在成功帖子后重定向(没有模型验证错误),否则你发回带有验证错误消息的页面.
Usually you only redirect after a successful post (no Model Validation errors), otherwise you send back the page with a validation error message.
PRG 模式可防止重复发布,因此发回同一页面(+ 错误消息)没有害处,因为发布未成功,除非发生变化,否则不会成功使验证通过.
The redirect in the PRG pattern prevents double-posting, so there's no harm to send back the same page (+ error message) because the post was not successful and will not be unless something changes to make validation pass.
编辑:
看起来您正在寻找将 ModelState
传递给下一个(重定向的)请求.这可以通过使用 TempData
来存储 ModelState
直到下一个请求来完成.仅供参考,TempData
使用 Session.
It looks like you're looking for passing ModelState
to the next (redirected) request. This can be done by using TempData
to store ModelState
up to the next request. FYI, TempData
uses Session.
这可以通过 ActionFilters
实现.示例可以在 MvcContrib 项目代码中找到:ModelStateToTempDataAttribute
This can be implemented with ActionFilters
. Examples can be found in the MvcContrib project code: ModelStateToTempDataAttribute
在 weblogs.asp.net(貌似作者已经搬了博客,但是我在新博客上找不到文章).来自文章:
This has also been mentioned together with other tips in a 'best practices' article on weblogs.asp.net (seems the author has moved the blog, but I couldn't find the article on the new blog). From the article:
这种模式的一个问题是当验证失败或任何发生异常时,您必须将 ModelState 复制到 TempData 中.如果你正在手动执行,请停止它,您可以自动执行此操作使用操作过滤器,如下所示:
One of the issue with this pattern is when a validation fails or any exception occurs you have to copy the ModelState into TempData. If you are doing it manually, please stop it, you can do this automatically with Action Filters, like the following:
控制器
[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard"), StoryListFilter, ImportModelStateFromTempData]
public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page)
{
//Other Codes
return View();
}
[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData]
public ActionResult Submit(string userName, string url)
{
if (ValidateSubmit(url))
{
try
{
_storyService.Submit(userName, url);
}
catch (Exception e)
{
ModelState.AddModelError(ModelStateException, e);
}
}
return Redirect(Url.Dashboard());
}
动作过滤器
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)
{
ModelStateDictionary 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);
}
}
这篇关于MVC3 模型验证最佳实践在发布/状态更改后重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!