1

ASP.NET MVC 2.0

我正在做 Post-Redirect-Get,如果我在发布时遇到错误,我需要包含 ModelErrors 以便沿着 -Redirect-Get 路线行驶。我通过“TempData”发送它:

TempData["modelErors"] = 
    ModelState.
        Where(item => item.Value.Errors.Count > 0).
        ToDictionary(
            item => item.Key, 
            item => item.Value.Errors.Select(error=>error.ErrorMessage).ToList()
        );

然后将其重新插入到 ModelState 中:

if (TempData.ContainsKey("modelErors")) {
    foreach (var errors in (IDictionary<string,IList<string>>) TempData["modelErors"]) {
        foreach (var error in errors.Value) {
            ModelState.AddModelError(errors.Key, error);
        }
    }
}

有没有更好的办法?

4

2 回答 2

2

在成功发布后,您真的应该只 PRG。否则,如果有错误,可以从帖子中返回。

否则,您需要使用 cookie、会话或请求变量来存储下一个请求的信息。

默认情况下,在 ASP.NET MVC2 中,我认为 TempData 使用会话状态来存储下一个请求的信息。

于 2010-06-25T14:24:53.347 回答
0

我认为最干净的解决方案是像这样使用 ActionFilterAttribute :

public class RedirectErrorAttribute : ActionFilterAttribute
{
    #region Methods & Function
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.Controller.TempData.ContainsKey("modelErrors"))
        {
            foreach (var errors in (Dictionary<string, List<string>>)filterContext.Controller.TempData["modelErrors"])
                foreach (var error in errors.Value)
                    filterContext.Controller.ViewData.ModelState.AddModelError(errors.Key, error);
        }

        base.OnActionExecuting(filterContext);
    }
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (filterContext.Controller.ViewData.ModelState.Values.Any(x => x.Errors.Count > 0))
        {
            if (filterContext.Controller.TempData.ContainsKey("modelErrors"))
                filterContext.Controller.TempData.Remove("modelErrors");
            else
            {
                filterContext.Controller.TempData["modelErrors"] =
                    filterContext.Controller.ViewData.ModelState.
                    Where(item => item.Value.Errors.Count > 0).
                        ToDictionary(
                            item => item.Key,
                            item => item.Value.Errors.Select(error => error.ErrorMessage).ToList()
                        );

                filterContext.Controller.TempData.Keep("modelErrors");
            }
        }

        base.OnResultExecuted(filterContext);
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        base.OnResultExecuting(filterContext);
    }

    #endregion
}

在您只需将属性放在引发错误的操作和收到错误的操作的顶部之后,如下所示:

[RedirectError]
public ActionResult Delete(Guid id)
{

[RedirectError]
public ActionResult Get(Guid id)
{

这就像一个具有干净可管理代码的魅力。

希望这个帮助!

朱利安

于 2011-04-20T18:00:47.420 回答