RedirectToAction으로 ModelState를 유지하려면 어떻게해야합니까?
ModelState 정보를 잃지 않고 ModelState에 오류가있는 경우 다른 작업의 결과를 반환하거나 사용자를 다른 작업으로 이동하려면 어떻게해야합니까?
시나리오는 다음과 같습니다. 삭제 작업은 내 색인 작업 /보기에서 렌더링 한 DELETE 양식에서 POST를 수락합니다. 삭제에 오류가있는 경우 사용자를 다시 색인 작업 /보기로 이동하고 .NET Framework에서 삭제 작업으로 저장된 오류를 표시합니다 ViewData.ModelState
. ASP.NET MVC에서 어떻게이 작업을 수행 할 수 있습니까?
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Delete)]
public ActionResult Delete([ModelBinder(typeof(RdfUriBinder))] RdfUri graphUri)
{
if (!ModelState.IsValid)
return Index(); //this needs to be replaced with something that works :)
return RedirectToAction("Index");
}
뷰 데이터를 TempData에 저장하고 인덱스 작업에서 검색합니다 (있는 경우).
...
if (!ModelState.IsValid)
TempData["ViewData"] = ViewData;
RedirectToAction( "Index" );
}
public ActionResult Index()
{
if (TempData["ViewData"] != null)
{
ViewData = (ViewDataDictionary)TempData["ViewData"];
}
...
}
[편집] MVC의 온라인 소스를 확인한 결과 Controller의 ViewData가 설정 가능한 것으로 보이므로 ModelState를 포함한 모든 ViewData를 Index 액션으로 전송하는 것이 가장 쉽습니다.
작업 필터 (PRG 패턴) 사용 (속성을 사용하는 것만 큼 쉬움)
tvanfosson의 솔루션이 항상 작동하는 것은 아니지만 대부분의 경우 괜찮을 것입니다.
특정 솔루션의 문제는 이미 ViewData 또는 ModelState가있는 경우 이전 요청의 상태로 모두 덮어 쓰게된다는 것입니다. 예를 들어, 새 요청에는 작업에 전달되는 잘못된 매개 변수와 관련된 일부 모델 상태 오류가있을 수 있지만 이러한 오류는 덮어 쓰기 때문에 숨겨집니다.
예상대로 작동하지 않을 수있는 또 다른 상황은 일부 ViewData 또는 ModelState 오류를 초기화 한 작업 필터가있는 경우입니다. 다시 말하지만, 해당 코드로 덮어 쓰게됩니다.
두 요청의 상태를 더 쉽게 병합 할 수있는 ASP.NET MVC 용 솔루션을 찾고 있으므로 계속 지켜봐주십시오.
고마워, Eilon
이것이 PRG를 사용하여 @bob의 권장 솔루션을 사용한 사람에게 유용한 경우 :
항목 13-> 링크 참조 .
VeiwBag에서 View로 전달되는 메시지가 추가 문제로 작성되고 컨트롤러 작업에서 TempData에서 수동으로 확인 /로드됩니다 RedirectToAction("Action")
. 단순화 (유지 보수 가능)하기 위해이 접근 방식을 약간 확장하여 다른 데이터도 확인하고 저장 /로드했습니다. 내 행동 방법은 다음과 같습니다.
[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");
}
그리고 내 색인 작업 :
[ImportModelStateFromTempData]
public ActionResult Index() {
ProfileViewModel pVM = new ProfileViewModel { //setup }
return View(pVM);
}
액션 필터의 코드 :
// Following best practices as listed here for storing / restoring model data:
// http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute {
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}
:
public class ExportModelStateToTempData : ModelStateTempDataTransfer {
public override void OnActionExecuted(ActionExecutedContext filterContext) {
//Only export when ModelState is not valid
if (!filterContext.Controller.ViewData.ModelState.IsValid) {
//Export if we are redirecting
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult)) {
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}
// Added to pull message from ViewBag
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) {
//Only Import if we are viewing
if (filterContext.Result is ViewResult) {
filterContext.Controller.ViewData.ModelState.Merge(modelState);
} else {
//Otherwise remove it.
filterContext.Controller.TempData.Remove(Key);
}
}
// Restore Viewbag message
if (!string.IsNullOrEmpty((string)filterContext.Controller.TempData["Message"])) {
filterContext.Controller.ViewBag.Message = filterContext.Controller.TempData["Message"];
}
base.OnActionExecuted(filterContext);
}
}
I realize my changes here are a pretty obvious extension of what was already being done with the ModelState by the code @ the link provided by @bob - but I had to stumble on this thread before I even thought of handling it in this way.
Maybe try
return View("Index");
instead of
return Index();
참고URL : https://stackoverflow.com/questions/279665/how-can-i-maintain-modelstate-with-redirecttoaction
'programing tip' 카테고리의 다른 글
Redux 상태 및 URL 해시 태그 매개 변수를 동기화하는 방법 (0) | 2020.11.01 |
---|---|
서식있는 텍스트 형식없이 코드를 복사하여 붙여 넣는 방법 (0) | 2020.11.01 |
HTML 텍스트 영역 가로 스크롤 (0) | 2020.11.01 |
반복기와 열거 자의 구별 (0) | 2020.11.01 |
문자열의 일부를 제거하지만 문자열의 끝에있을 때만 (0) | 2020.11.01 |