【问题标题】:Should RenderAction be used with forms?RenderAction 应该与表单一起使用吗?
【发布时间】:2010-01-10 05:14:26
【问题描述】:

我的设置:

  • 查看如下路线:/Pages/Details/2
  • 页面详情视图有<% Html.RenderAction("CreatePageComment", "Comments"); %>来呈现评论表单
  • 评论表帖子到Comments/CreatePageComment
  • 成功创建评论时,/Comments/CreatePageComment 返回RedirectToAction
  • 这一切都很好

我的问题:

如果出现验证错误,我应该如何返回/Pages/Detail/1 并在评论表单中显示错误?

  • 如果我使用RedirectToAction,验证似乎很棘手;我是否应该使用 Post-Redirect-Get 模式来验证错误,而不是仅仅返回?
  • 如果我返回 View(),它会让我回到显示 CreateComment.aspx 视图(带有验证,但只是白页上的一个表单),而不是调用 RenderAction 的 /Pages/Details/2 路由。

如果应该使用 PRG 模式,那么我想我只需要学习如何在使用 PRG 时进行验证。如果不是——在我看来,这似乎通过返回 View() 更好地处理——然后我不知道如何让用户在使用 RenderAction 时返回到初始视图,显示表单错误。

这感觉就像是同时敲打头部和揉腹部的游戏。我也不擅长那个。我是 MVC 的新手,所以这可能是这里的问题。

【问题讨论】:

  • 顺便说一句:我可以通过使用 Partial 和 POST 路由 /Page/CreateComment 来实现这一点,但这看起来不是很混乱吗?我想让我的 Comments 控制器处理 cmets,而不是 Page 控制器。奇怪的是,我刚刚查看了 Oxite 博客引擎代码,他们的 Post 控制器处理添加评论;他们的 Comments 控制器甚至没有 Create 动作!

标签: asp.net-mvc renderaction post-redirect-get


【解决方案1】:

我相信答案是使用TempData,例如:

在我看来(/Steps/Details)我有:

<!-- List comments -->
<% Html.RenderAction("List", "Comments", new { id = Model.Step.Id }); %>

<!-- Create new comment -->
<% Html.RenderAction("Create", "Comments", new { id = Model.Step.Id }); %>

在我的 cmets 控制器中,我有我的 POST 方法:

    // 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 });
        }
    }

cmets 控制器中还有我的 GET 方法:

    //
    // 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 });
    }

这对我来说非常有用,但我希望能就这是否是一种好的做法等提供反馈。

另外,我注意到 MvcContrib 有一个 ModelStateToTempData 装饰,看起来可以做到这一点,但方式更简洁。接下来我要试试。

【讨论】:

  • 我遇到了类似的问题。您提出的解决方案似乎有效,但我很好奇是否没有更清洁的方法。对我来说,您的解决方案似乎更像是一个黑客而不是真正的解决方案。不知道大家对此有没有其他意见?
  • 是的,它确实让人觉得很hackish,但这是我能找到的所有工作。像你一样,我欢迎更清洁的解决方案。
  • 在我的研究中,我发现 MvcContrib 库中有一个叫做 SubController 的东西,也许可以解决这类问题。我没有再看下去,但它似乎很有趣。
  • @Melursus。我现在更多地使用了 renderaction,包括表单和 AJAX,并且效果很好。绝妙的是,partials 在渲染操作视图中也能很好地工作,包括 AJAX 回调。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
相关资源
最近更新 更多