请参阅使用 RedirectToAction 时如何维护 ModelState 错误?.
可TempData
用于保存ModelState
数据ViewModel
。
public class SomeController : Controller
{
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = TempData["ModelState"];
if (modelState != null && !ModelState.Equals(modelState))
{
ModelState.Merge((ModelStateDictionary)modelState);
}
base.OnActionExecuted(filterContext);
}
private void SetModelState(ModelStateDictionary modelState)
{
TempData["ModelState"] = modelState;
}
private void SetViewModel(SqlAdminViewModel viewModel)
{
TempData["ViewModel"] = viewModel;
}
private SomeViewModel GetViewModel()
{
var viewModelTempData = TempData["ViewModel"];
var viewModel = viewModelTempData != null
? (SomeViewModel) TempData["ViewModel"]
: BuildSomeViewModel();
return viewModel;
}
public ActionResult Index()
{
var viewModel = GetViewModel();
return View(viewModel);
}
[HttpPost]
public ActionResult Method(SomeMethodViewModel model)
{
if(HasError(model))
{
var viewModel = GetViewModel();
viewModel.SomeMethod = model;
SetViewModel(viewModel);
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
privare bool HasError(SomeMethodViewModel model)
{
var hasError = false;
// Model validation logic
if(hasError)
{
SetModelState(ModelState);
}
return hasError;
}
}
这可以进一步解耦:
public interface IViewModelValidator<in TViewModel>
{
bool HasError(TViewModel viewModel, ModelStateDictionary modelState);
bool HasError(TViewModel viewModel, ModelStateDictionary modelState, Action<ModelStateDictionary> callBack);
}
public abstract class ViewModelValidatorBase<TViewModel> : IViewModelValidator<TViewModel>
{
public abstract bool HasError(TViewModel viewModel, ModelStateDictionary modelState);
public virtual bool HasError(TViewModel viewModel, ModelStateDictionary modelState, Action<ModelStateDictionary> callBack)
{
var hasError = HasError(viewModel, modelState);
if (hasError && callBack != null)
{
callBack(modelState);
}
return hasError;
}
}
用法:
[HttpPost]
public ActionResult Method(SomeMethodViewModel model)
{
if(_someMethodViewModelValidator.HasError(model, ModelState, SetModelState))
{
var viewModel = GetViewModel();
viewModel.SomeMethod = model;
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}