2010-06-25 37 views
1

ASP.NET MVC 2.0如何傳遞ModelErrors以及重定向?

我正在做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); 
     } 
    } 
} 

有沒有更好的辦法?

回答

2

你真的應該只有在成功發佈PRG後。否則,如果出現錯誤,可以從帖子返回。

否則,您需要使用cookie,會話或請求變量來存儲下次請求的信息。

在ASP.NET MVC2默認情況下,我認爲TempData使用會話狀態來存儲下一個請求的信息。

+0

+1這是真的,你應該只發出一個get,如果請求被驗證爲OK。 – 2010-06-25 15:42:25

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) 
{ 

這就像一個乾淨的可管理代碼的魅力。

希望這個幫助!

Julien