Falls dies für jemanden nützlich ist, habe ich die von @bob empfohlene Lösung mit PRG verwendet:
siehe Punkt 13 -> Link .
Ich hatte das zusätzliche Problem, dass Nachrichten in der VeiwBag an die Ansicht übergeben und manuell aus TempData in den Controller-Aktionen überprüft / geladen wurden, wenn a ausgeführt wurde RedirectToAction("Action"). Um zu vereinfachen (und auch wartbar zu machen), habe ich diesen Ansatz leicht erweitert, um auch andere Daten zu überprüfen und zu speichern / laden. Meine Handlungsmethoden sahen ungefähr so aus:
[AcceptVerbs(HttpVerbs.Post)]
[ExportModelStateToTempData]
public ActionResult ChangePassword(ProfileViewModel pVM) {
bool result = MyChangePasswordCode(pVM.ChangePasswordViewModel);
if (result) {
ViewBag.Message = "Password change success";
else {
ModelState.AddModelError("ChangePassword", "Some password error");
}
return RedirectToAction("Index");
}
Und meine Indexaktion:
[ImportModelStateFromTempData]
public ActionResult Index() {
ProfileViewModel pVM = new ProfileViewModel {
return View(pVM);
}
Der Code in den Aktionsfiltern:
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute {
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}
::
public class ExportModelStateToTempData : ModelStateTempDataTransfer {
public override void OnActionExecuted(ActionExecutedContext filterContext) {
if (!filterContext.Controller.ViewData.ModelState.IsValid) {
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult)) {
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}
if (!string.IsNullOrEmpty(filterContext.Controller.ViewBag.Message)) {
filterContext.Controller.TempData["Message"] = filterContext.Controller.ViewBag.Message;
}
base.OnActionExecuted(filterContext);
}
}
::
public class ImportModelStateFromTempData : ModelStateTempDataTransfer {
public override void OnActionExecuted(ActionExecutedContext filterContext) {
ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
if (modelState != null) {
if (filterContext.Result is ViewResult) {
filterContext.Controller.ViewData.ModelState.Merge(modelState);
} else {
filterContext.Controller.TempData.Remove(Key);
}
}
if (!string.IsNullOrEmpty((string)filterContext.Controller.TempData["Message"])) {
filterContext.Controller.ViewBag.Message = filterContext.Controller.TempData["Message"];
}
base.OnActionExecuted(filterContext);
}
}
Mir ist klar, dass meine Änderungen hier eine ziemlich offensichtliche Erweiterung dessen sind, was bereits mit dem ModelState durch den Code @ the link von @bob gemacht wurde - aber ich musste über diesen Thread stolpern, bevor ich überhaupt daran dachte, ihn auf diese Weise zu handhaben.