【问题标题】:POST method called on MVC UserControls as well as their parent views在 MVC 用户控件及其父视图上调用 POST 方法
【发布时间】:2010-04-23 14:42:47
【问题描述】:

重写:我原来的帖子似乎被误解了。此后,我将其报告为具有以下描述的错误。这个问题的原帖可以在第二个<HR>下面找到。


我对用户控件中的 POST 有一个重大问题。

  • 我有一个 UserControl,它有一个控制器,其中包含两个名为“ContactForm”的 ActionMethod。第二个有 ActionVerb.POST 以响应回发。用户控件主要通过 AJAX 使用——但这实际上与这里无关。显然,这些操作方法会渲染局部视图。

  • 我有一个主页,其中包含一个用于“EnterContest”的附加 html 表单。再一次 - 它的控制器有两个称为“EnterContest”的 ActionMethod,其中一个响应 ActionVerb.POST。此视图包含侧栏中的“ContactForm”,其呈现方式为:

    <% Html.RenderAction("ContactUsForm", "Company", new { commentsBoxHeader = "Questions" }); %>

回发“EnterContest”表单(视图上的主表单)时会出现问题。

来自 Fiddler 的 POST 请求仅包含此查询字符串(显然不包含来自联系我们表单的任何 POST 数据,因为那是一个完全独立的 HTTP 操作)。

contestId=ND09&email=fred&btnEnterContest=提交

(是的,这看起来像 GET 但仅此而已 Fiddler 也为 POST 显示的内容)

  • 首先 - (如预期) - 在主控制器中调用 'EnterContest(FormCollection data) 方法。这会处理表单提交以进入比赛 - 调用网络服务等。

  • 第二个 - (不是预期的) - 调用“ContactForm”控制器的 POST 方法。这会立即崩溃,因为它缺少预期的参数——而且我们不希望它被调用。这发生在同一个 Http 请求期间。

如果我查看堆栈跟踪 - 它是从动态生成的 aspx 页面调用的 - 源自上面显示的 Html.RenderAction 代码行。所以很明显,正在发生的事情是希望部分呈现“ContactUs”操作方法的代码查看请求并看到有一种方法可以处理 POST,因此它将它路由到那里 - 这是非常糟糕的。它可能在框架中这个方法的某个地方:

System.Web.Mvc.dll!System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod

这种行为非常令人困惑,并且确实破坏了看似简单的页面。我很确定这是一个错误——因为如果没有一些非常笨拙的检查我的控制器,我就看不到一个优雅的工作。我认为 RenderAction 在未来 - 但我不知道问题是否存在于那里或主框架中。

只是为了澄清没有发生的事情:

  • 任何聪明的 jQuery
  • 多个 HTTP 请求(在 Fiddler 中验证)
  • 嵌套表单

谢谢


原帖

我在 ASP.NET MVC 中使用RenderAction Html 扩展。

我遇到了一些出乎意料的事情,但我想起来更有意义。

假设我有一个包含“RenderAction”方法的视图,用于为页面的一部分生成联系人。

<% Html.RenderAction("ContactUsForm", "Company", 
   new { commentsBoxHeader = "Questions" }); %>

在这种情况下,它生成的部分视图会创建一个通过&lt;%= Html.BeginAjaxForm() %&gt; 回发的ajax 表单。

所以我当然需要一个 actionresult 来处理 AJAX 回发。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ContactUsForm(FormCollection formdata)

现在,当包含此部分渲染操作的 父视图 具有带有 POST 操作的普通(非 ajax)表单时,就会出现问题。除了主视图的 POST 操作之外,还会调用 ContactUsForm 操作的 POST 方法。在此操作中,formdata 属性包含父视图的所有属性 - 所以ContactUsForm 会因空引用或类似的东西而死。

我想出了 3 种可能的解决方案:

1) 为页面上的任何用户控件的回发创建不同的操作名称。这样做的缺点是您必须回发到与创建局部视图不同的函数。通常这可能会更麻烦,但这就是我现在正在做的事情。

2) 检查每个 POST 方法(您必须记住在每个用户控件的 POST 操作方法中运行此检查)以查看表单数据是否用于该表单,如果不是则返回默认视图。

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResultContactUsForm(FormCollection formData)
    {
        if (formData["btnSubmitContactUsForm"] == null) {

            // "This form is not for us!";
            // figure out how (if is possible) to return the get default view here
            // and call it with the right arguments
        }
    } 

3) 将其报告为错误。

我应该在这里做什么?我倾向于认为这是一个错误

编辑:我需要强调的一件非常重要的事情是,两个 POST 方法都被调用 - 所以它不仅仅是像嵌套表单那样的东西。

编辑 2: 在 Fiddler 中我只看到一个请求。问题是当它在为我的主页处理 POST 后尝试渲染 ContactUsForm 时,它会点击 'ContactUsForm' 的 'POST' 方法而不是非 post 处理程序。

【问题讨论】:

  • 好奇:你用的是什么 DOCTYPE?
  • ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" rel="nofollow" target="_blank">w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> w3.org/1999/xhtml">

标签: asp.net-mvc


【解决方案1】:

EDIT2:我刚刚注意到您使用的是 RenderAction 而不是 RenderPartial。我怀疑正在发生的事情是它使用已发布表单的 RequestContext 来选择在调用 RenderAction 时选择哪个 ContactUsForm 方法。这可以说是正确的行为,因为动作 正在 是从回发中调用的,而不是您想要的。我会以完全不同的方式处理这个问题。由 ViewUserControl 生成部分,并使用 RenderPartial 将其包含在页面上。删除 GET ContactUsForm 方法,只有 POST 版本。也就是说,表单本身是作为 ViewUserControl 生成的,带有预先确定的标记或通过 ViewData 传递的参数动态生成的标记。表单响应通过控制器操作处理。

编辑:既然您指出嵌套不是问题,那么您是否有可能使用 javascript(比如 jQuery)来触发提交并且您的选择器过于宽泛。例如,如果您有如下代码,这将解释您所看到的行为。

$(document).ready( function() {
    $('#mybutton').click( function() {
       $('form').submit();
    });
});

原答案:(留作上下文)

听起来您的视图中有嵌套表单。尝试将 RenderAction 移到父视图中的表单之外,看看是否能解决您的问题。我对 MVC 视图中的表单的感觉是它们应该是紧凑的,并且只覆盖包含实际输入的标记。这是 WebForms 的一个变化,在 WebForms 中,您通常将所有标记都包含在表单中。如果您需要让表单元素看起来是混合的,请使用 CSS 来控制布局。

【讨论】:

  • 那是我没有想到的,但就我而言,这不是问题。我在完全不同的区域有两种表格,我刚刚验证了标签没有重叠。这绝对是要注意的事情。可能会导致一些意想不到的症状!
  • @Simon:如果是这样的话,那么我将把整个部分改写为“现在问题发生时......”,因为该段导致读者假设您的问题与嵌套形式有关。
  • @tvanfosson - 抱歉,我似乎放弃了这篇文章一天。我现在回来了,我已经用更多的说明重写了这个问题。我几乎已经断定它是一个错误并想知道解决方法。
【解决方案2】:

这实际上是带有 MVC 功能库的 ASP.NET MVC 1.0 和 ASP.NET MVC 2.0 中已确认的错误。 当请求为 POST 时,RenderAction 行为不正确。 我已在 Codeplex 上的 ASP.NET 问题跟踪器中提交了该错误,请为它投票 :) http://aspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=5847

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2014-11-30
    • 2014-11-13
    • 1970-01-01
    • 2018-01-14
    • 2011-09-27
    • 1970-01-01
    相关资源
    最近更新 更多