提交按钮是否在表单提交时将其值传递给操作方法?

Does submit button passes its value to action method, on form submit?

更新:

当表单 post 返回时,将提交其值的 control/fields 是什么?


在ASP.NET MVC 表单中,如果用户双击提交按钮,表单将被提交两次。为了解决这个问题,我实施了解释的解决方案 here

这是我的解决方案,我禁用了表单提交上的提交按钮,因此无法再次点击它:

function preventFromBeingDoubleSubmitted() {
    $('form').each(function () {
        $(this).submit(function (e) {
            if ($("form").valid()) {
                // if form is valid, then disable the submit button so it cannot be double clicked (double submitted)
                $(this).find(':submit').attr('disabled', 'disabled');
            }
        });
    });
}

$(document).ready(function () {
    preventFromBeingDoubleSubmitted();
});

这工作正常,但我得到一个非常奇怪的行为 ASP.NET 内置身份代码。我的登录页面,允许用户使用 Facebook 或 Google 登录(每个按钮都是提交按钮):

这是生成上述登录表单的代码(这是内置身份模板):

@{
    var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes();
    if (loginProviders.Count() > 0)
    {
        using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = Model.ReturnUrl }))
        {
            @Html.AntiForgeryToken()
            <div class="form-group">
                @foreach (AuthenticationDescription p in loginProviders.OrderBy(o => o.Caption))
                {
                    if (string.Equals(p.AuthenticationType, "google", StringComparison.InvariantCultureIgnoreCase))
                    {
                        <button type="submit" class="external-login-btn btn-google" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Log in using your @p.Caption account">Log in with @p.AuthenticationType</button>
                    }
                    if (string.Equals(p.AuthenticationType, "facebook", StringComparison.InvariantCultureIgnoreCase))
                    {
                        <button type="submit" class="external-login-btn btn-facebook" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Log in using your @p.Caption account">Log in with @p.AuthenticationType</button>
                    }
                }
            </div>
        }
    }
}

以上代码,应该命中以下Controller Action(内置身份模板):

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
    return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}

添加.js代码防止重复提交后,外部登录失效了。问题是,当用户单击 使用 Facebook 按钮登录时,提供商名称不再传递到 ExternalLogin 操作。

如果我删除 preventFromBeingDoubleSubmitted() 函数,提供程序名称将被传递到 ExternalLogin 操作方法中,一切正常。

我不明白的是,provider 最初是如何传递给 action 方法的?为什么禁用按钮会阻止提供程序被传入?

我先回答这个问题:

What I don't understand is, how is provider passed in to action method at the first place?

您有一个带有 name="provider" value="@p.AuthenticationType" 的按钮,此代码将提供商名称传递给您的操作方法。

下一个:

And why disabling the button prevents provider from being passed in?

提交表单时,禁用字段的值不会传递到服务器。这是默认行为。

现在要解决这个问题,我们可以隐藏按钮而不是禁用它。因此,在您的 preventFromBeingDoubleSubmitted() 中,您可以将 $(this).find(':submit').attr('disabled', 'disabled'); 更改为 $(this).find(':submit').hide();

希望对您有所帮助。

更新

回答有关表单数据中包含哪些字段的新问题。

  1. <input>
  2. <button>
  3. <option>

HTML 表单是文档的一部分,其中包含正常内容、标记、称为控件(复选框、单选按钮、菜单等)的特殊元素以及这些控件上的标签。用户通常 "complete" 在将表单提交给代理进行处理(例如,Web 服务器、邮件服务器等)之前,通过修改其控件(输入文本、选择菜单项等)来 "complete" 表单

用户通过命名控件与表单交互。

控件的 "control name" 由其名称属性给出。 FORM 元素中控件的名称属性的范围是 FORM 元素。

HTML 定义了以下控件类型:

  • 按钮
  • 复选框
  • 单选按钮
  • 菜单:菜单为用户提供可供选择的选项。 SELECT 元素结合 OPTGROUP 和 OPTION 元素创建一个菜单。
  • 输入控件(数字、文本等)
  • 隐藏控件
  • 对象控件:作者可以在表单中插入通用对象,以便将关联值与其他控件一起提交。作者使用 OBJECT 元素创建对象控件。

因为按钮是控件,所以按钮的值将发布到服务器(如果按钮像您的示例一样具有名称和值)。所以它是关于 html 规范的。不是 asp.net mvc,不是微软的规范

您可以参考这些链接了解更多详情