我開始走下這條路,然後閱讀你的答案。我將它們結合在一起爲以下文件:
TempDataDictionaryExtensions.cs
我創建擴展方法做就TempData的骯髒的工作,因爲我覺得它沒有在行動過濾器本身屬於。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace Project.Web.UI.Domain
{
public static class TempDataDictionaryExtensions
{
private const string _ModelStateErrorsKey = "ModelStateErrors";
public static IEnumerable<string> GetModelErrors(this TempDataDictionary instance)
{
return TempDataDictionaryExtensions.GetErrorsFromTempData(instance);
}
public static void AddModelError(this TempDataDictionary instance, string error)
{
TempDataDictionaryExtensions.AddModelErrors(instance, new List<string>() { error });
}
public static void AddModelErrors(this TempDataDictionary instance, IEnumerable<string> errors)
{
TempDataDictionaryExtensions.AddErrorsToTempData(instance, errors);
}
private static List<string> GetErrorsFromTempData(TempDataDictionary instance)
{
object tempObject = instance.FirstOrDefault(x => x.Key == TempDataDictionaryExtensions._ModelStateErrorsKey);
if (tempObject == null)
{
return new List<String>();
}
List<string> tempErrors = instance.FirstOrDefault(x => x.Key == TempDataDictionaryExtensions._ModelStateErrorsKey).Value as List<string>;
if (tempErrors == null)
{
return new List<String>();
}
return tempErrors;
}
private static void AddErrorsToTempData(TempDataDictionary instance, IEnumerable<string> errors)
{
List<string> tempErrors;
object tempObject = instance.FirstOrDefault(x => x.Key == TempDataDictionaryExtensions._ModelStateErrorsKey);
if (tempObject == null)
{
tempErrors = new List<String>();
}
else
{
tempErrors = instance.FirstOrDefault(x => x.Key == TempDataDictionaryExtensions._ModelStateErrorsKey).Value as List<string>;
if (tempErrors == null)
{
tempErrors = new List<String>();
}
}
tempErrors.AddRange(errors);
instance[TempDataDictionaryExtensions._ModelStateErrorsKey] = tempErrors;
}
}
}
TempDataModelStateAttribute.cs
我的原創,複製出來的TempData
錯誤回到ModelState
通過OnResultExecuting
執行的ActionResult之前。這是將它們複製到TempData
並退出的組合。
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace Project.Web.UI.Domain
{
public class TempDataModelStateAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
IEnumerable<string> modelErrors = ((Controller)filterContext.Controller).TempData.GetModelErrors();
if (modelErrors != null
&& modelErrors.Count() > 0)
{
modelErrors.ToList()
.ForEach(x => ((Controller)filterContext.Controller).ModelState.AddModelError("GenericError", x));
}
base.OnResultExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
if (filterContext.Result is RedirectResult
|| filterContext.Result is RedirectToRouteResult)
{
List<string> errors = new List<string>();
foreach (var obj in filterContext.Controller.ViewData.ModelState.Values)
{
foreach (var error in obj.Errors)
{
errors.Add(error.ErrorMessage);
}
}
((Controller)filterContext.Controller).TempData.AddModelErrors(errors);
}
}
base.OnActionExecuted(filterContext);
}
}
}
什麼概念呢?你能更具體嗎? – Kassem 2012-06-19 11:20:04
它看起來像你試圖實現稱爲PRG(Post/Redirect/Get)的概念/模式。以下鏈接我已經提供或檢查CodePlex上的MvcContrib項目應該給你一個很好的解釋模式本身加上實現的例子 – ITmeze 2012-07-20 10:49:07