开发者

Should RenderAction be used with forms?

My setup:

  • Have a view for a route like: /Pages/Details/2
  • The page details view has <% Html.RenderAction("CreatePageComment", "Comments"); %> to render a comment form
  • Comment form posts to Comments/CreatePageComment
  • /Comments/CreatePageComment returns RedirectToAction when a comment is created successfully
  • This all works nicely

My question:

If there is a validation error, how should I return to /Pages/Detail/1 and show the error in the comment form?

  • If I use RedirectToAction, it seems validation is tricky; should I even be using the Post-Redirect-Get pattern for validation errors, instead of just returnin开发者_JAVA技巧g?
  • If I return 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜