My setup:
/Pages/Details/2
<% Html.RenderAction("CreatePageComment", "Comments"); %> to render a comment formComments/CreatePageComment
/Comments/CreatePageComment returns RedirectToAction when a comment is created successfullyMy question:
If there is a validation error, how should I return to /Pages/Detail/1 and show the error in the comment form?
RedirectToAction, it seems validation is tricky; should I even be using the Post-Redirect-Get pattern for validation errors, instead of just returning?View() it kicks me back to showing the CreateComment.aspx view (with validation, but just a form on a white page), not the /Pages/Details/2 route that called the RenderAction.If the PRG pattern should be used, then I think I just need to learn how to do validation while using PRG. If not — and to me this seems better handled by returning View() — then I don't know how to get the user returned to the initial view, showing the form errors, while using RenderAction.
This feels like the game where you tap your head and rub your belly at the same time. I wasn't good at that one either. I'm new at MVC, so that's likely the problem here.
I believe the answer is to use TempData, for example:
In my view (/Steps/Details) I have:
<!-- List comments -->
<% Html.RenderAction("List", "Comments", new { id = Model.Step.Id }); %>
<!-- Create new comment -->
<% Html.RenderAction("Create", "Comments", new { id = Model.Step.Id }); %>
In my comments controller I have my POST method:
// POST: /Comments/Create
[HttpPost]
public ActionResult Create([Bind(Exclude = "Id, Timestamp, ByUserId, ForUserId")]Comment commentToCreate)
{
if (ModelState.IsValid)
{
//Insert functionality here
return RedirectToAction("Details", "Steps", new { id = commentToCreate.StepId });
}
//If validation error
else
{
//Store modelstate from tempdata
TempData.Add("ModelState", ModelState);
//Redirect to action (this is hardcoded for now)
return RedirectToAction("Details", "Steps", new { id = commentToCreate.StepId });
}
}
Also in the comments controller is my GET method:
//
// GET: /Comments/Create
public ActionResult Create(int id)
{
if (TempData.ContainsKey("ModelState"))
{
ModelStateDictionary externalModelState = (ModelStateDictionary)TempData["ModelState"];
foreach (KeyValuePair<string, ModelState> valuePair in externalModelState)
{
ModelState.Add(valuePair.Key, valuePair.Value);
}
}
return View(new Comment { StepId = id });
}
This works great for me, but I'd appreciate feedback on whether this is a good practice, etc.
Also, I noticed that MvcContrib has a ModelStateToTempData decoration that appears to do this, but in a cleaner way. I'm going to try that next.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With