私はこの道を進み始め、それからあなたの答えを読みました。それらを次のファイルに結合しました。
TempDataDictionaryExtensions.cs
TempDataがアクションフィルター自体に属していないと感じたため、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
私のオリジナルは、ActionResultがを介して実行される前に、エラーをコピーしてTempData
戻しました。これは、それらをコピーしてコピーしたり、元に戻したりすることの組み合わせです。ModelState
OnResultExecuting
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);
}
}
}