【问题标题】:MVC traditional form action not calling controller methodMVC 传统表单动作不调用控制器方法
【发布时间】:2015-08-27 21:48:04
【问题描述】:

我知道这个话题引起了很多开发者的兴趣,并且在很多论坛上都讨论过,但是我一直没能找到完全解决我的问题的正确答案。也许我还没有努力寻找答案,在这种情况下,如果你们开发人员可以让我知道任何有用的论坛,那就太好了。

我遇到的问题只是传统的 HTML 动作没有调用控制器的 ActionResult 方法。

我有一个名为“_Form.cshtml”的局部视图,如下所示:

<_form.cshtml>

<form action="@Url.Action("Temp_Form", "Product")" method="post" class="k-content" id="tempForm">
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    <fieldset>
    <p class="lead">Please fill in the following form.</p>
    <br />

    <div class="form-horizontal">
        <div class="form-group">
            @Html.Label("Brand", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @(Html.Kendo().DropDownList()
                .Name("ddlBrand")
                .OptionLabel("--- Select ---")
                .HtmlAttributes(new { id = "brand", required = "required", data_required_msg = "Select Brand", @class = "form-control" })
                .DataTextField("Name")
                .DataValueField("Id")
                .BindTo(Products.ProductBrandCollection.LoadAll())
                )
                <span class="k-invalid-msg" data-for="ddlBrand"></span>
            </div>
        </div>
        <div class="form-group">
            @Html.Label("Range", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @(Html.Kendo().TextBox()
                .Name("tbRange")
                .HtmlAttributes(new { required = "required", validationmessage = "Enter Range" })
                )
                <span class="k-invalid-msg" data-for="tbRange"></span>
            </div>
        </div>
    </div>

    <div id="buttondiv">
        <div class="column">
            <div class="vis" id="submitbutton">
                @(Html.Kendo().Button()
                .Name("btnSubmit")
                .HtmlAttributes(new { type = "submit", @class = "button-next" })
                .Icon("arrowhead-e")
                .Content("SUBMIT")
                .Events(e => e.Click("submit"))
                )
            </div>
        </div>
    </div>
    </fieldset>
</form>

在主视图“Product.cshtml”中,我有以下提交按钮的javascript点击事件:

function submit(e) {
    // handles hiding and showing divs
}

这是我的 ActionResult "Temp_Form",它在 "ProductController.cs" 中:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Temp_Form(string ddlBrand, string tbRange)
{
    TempData["brand"] = ddlBrand;
    TempData["range"] = tbRange;
    return Content("");
}

我怀疑它是 "@Url.Action("ActionMethod", "Controller")" e .Click("submit"))" 提交按钮。

**出于某种原因,我没有使用 Html.BeginForm() 来调用控制器方法。所以我的选择是使用传统的表单通过提交按钮将数据从视图传递到控制器。

我也试过了..

<form action="myController/myAction" method="POST">

上述格式,但我的 ActionResult 仍然没有被调用。

我认为我的主视图不会导致 ActionResult 不触发,因为它只有两个级联 DropDownLists 可以在客户端选择正确的表单。

有人可以找出我做错了什么或建议我用替代方法吗?正如我上面提到的,我没有任何机会使用 Html.BeginForm() 仅仅是因为我有那些似乎只适用于传统形式的 Telerik Kendo Validations..

非常感谢!

【问题讨论】:

  • 你为什么不使用Html.BeginForm()?为什么在表单标签之外有@Html.AntiForgeryToken()?您的function submit(e) { 中的代码是什么?
  • “我没有任何机会使用 Html.BeginForm() 仅仅是因为我有那些似乎只适用于传统形式的 Telerik Kendo 验证..” 出于某些原因,如果我更改为 Html .BeginForm(),验证消息不会出现。我删除了 submit(e) 只是因为我认为它与这个主题无关,因为它只处理隐藏和显示 div。
  • 不熟悉剑道验证,但可能是因为@Html.BeginForm() 将添加novalidate="novalidate"(但您可以轻松使用@Html.BeginForm() 并将novalidate 属性设置为空字符串。但是这与您的问题无关,因为 action="@Url.Action("Temp_Form", "Product")" 将生成正确的 url。您可以通过注释掉 @(Html.Kendo().Button()... 并替换为 &lt;input type="submit" /&gt; 来轻松测试这一点,然后应该发布到您的方法中。
  • 在这种情况下,您的Temp_Form() 方法是否用[ValidateAntiForgeryToken] 属性修饰? (如果不是它不会命中方法)
  • 健全性检查:(a) 如果您不处理 JS 中的提交事件会发生什么? (b) 检查您的浏览器工具并查看请求/响应流量(甚至脚本错误,如果您在管道中有 js)。

标签: asp.net-mvc forms actionresult


【解决方案1】:

你使用的是 Razor 语法所以不要直接使用表单标签,使用Html.BeginForm() 如下。

@using(Html.BeginForm("Temp_Form", "Product", FormMethod.Post, new {@class = "k-content", @id="tempForm" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    <fieldset>
        //your HTML here
    </fieldset>
}

如果可能的话,使用强类型模型而不是松散的字符串属性,如 ddlBrand 和 tbRange。

【讨论】:

    【解决方案2】:

    问题是您正在使用 JavaScript 事件处理表单的提交...

    因此,如果您想为提交按钮单击保留 JS 事件,您需要使用 JS 方法中的 Ajax 调用来执行 POST 到操作,例如:

    $.ajax({
        url: '/Product/Temp_Form',
        data: $('#tempForm').serialize(),
        type: 'POST',
    });
    

    【讨论】:

    • 所以我最终使用了@Aram 的方式,并且一切都按照我希望我的系统执行的方式运行。谢谢你的建议!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 2014-06-17
    • 2018-08-24
    • 2021-04-22
    相关资源
    最近更新 更多