MVC3 模型验证最佳实践在发布/状态更改后重定向 [英] MVC3 model validation best practice redirect after post / state change

查看:18
本文介绍了MVC3 模型验证最佳实践在发布/状态更改后重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于网络应用程序应始终在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆