鉴于网络应用程序应始终在POST后重定向(或任何不可重复的请求以更改服务器端状态)......
......人们如何使用MVC3模型验证和执行强制重定向?
答案 0 :(得分:7)
通常只有在成功帖子后才会重定向(没有模型验证错误),否则您会发回包含验证错误消息的页面。
PRG模式中的重定向可防止双重发布,因此发回同一页面(+错误消息)没有坏处,因为帖子不成功且不会除非有什么改变才能通过验证。
修改强>:
看起来您正在寻找将ModelState
传递给下一个(重定向)请求。这可以通过使用TempData
将ModelState
存储到下一个请求来完成。仅供参考,TempData
使用会话。
这可以使用ActionFilters
来实现。可以在MvcContrib项目代码中找到示例:ModelStateToTempDataAttribute
这也与weblogs.asp.net上的“最佳实践”文章中的其他提示一起被提及(似乎作者已经移动了博客,但我在新博客上找不到该文章)。来自文章:
此模式的一个问题是验证失败或任何问题 发生异常时,您必须将ModelState复制到TempData中。如果你 正在手动完成,请停止它,你可以自动执行此操作 使用动作过滤器,如下所示:
控制器
[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);
}
}
答案 1 :(得分:0)
“强制”重定向是什么意思?通常我们在控制器中使用try / catch,如果尝试成功,您可以重定向到View(如果您需要),也可以返回任何部分视图或任何您需要的视图。捕获通常会重新显示原始页面并显示错误消息,因为发布请求不成功。
希望我没有误会你:)