Как передать ModelErrors вместе с перенаправлением? - PullRequest
1 голос
/ 25 июня 2010

ASP.NET MVC 2.0

Я делаю Post-Redirect-Get, если я получаю ошибки на post, мне нужно включить 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);
        }
    }
}

Есть ли лучший способ?

Ответы [ 2 ]

2 голосов
/ 25 июня 2010

Вы должны действительно только PRG после успешного поста.В противном случае можно вернуться с поста в случае ошибки.

В противном случае вам необходимо использовать файлы cookie, переменные сессии или запроса для хранения этой информации для следующего запроса.

В ASP.NET MVC2по умолчанию я думаю, что TempData использует состояние сеанса для хранения информации для следующего запроса.

0 голосов
/ 20 апреля 2011

Я думаю, что наиболее чистым решением было использование 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)
{

И это работает как шарм с чистым управляемым кодом.

Надеюсь, эта помощь!

Julien

...