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