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

Posted

技术标签:

【中文标题】提交按钮是不是在表单提交时将其值传递给操作方法?【英文标题】:Does submit button passes its value to action method, on form submit?提交按钮是否在表单提交时将其值传递给操作方法? 【发布时间】:2019-08-25 18:21:34 【问题描述】:

更新:

表单回发时将提交其值的控件/字段是什么?


在 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代码防止重复提交,外部登录不再起作用。问题是,当用户点击 Login with Facebook 按钮时,提供者名称不再传递给ExternalLogin Action。

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

我不明白的是,提供者首先是如何传递给操作方法的?为什么禁用按钮会阻止提供者被传入?

【问题讨论】:

看起来您在页面完全加载后立即调用禁用函数。这意味着您将完全禁用它,而不是在第一次单击后禁用它。你应该使用 $(document).on('click', 'form', function () ...);而是 我不认为是这种情况,因为禁用是在提交时发生的......另外我可以点击按钮,所以它没有被禁用......它只有在我点击时才会被禁用在按钮上并提交表单。 请不要将您的问题编辑成一个完全不同的问题。 @Rob:感谢您的评论...我的问题是表单提交时将提交哪些表单控件...两个答案都解释了这个问题。我删除 ASP.NET 身份代码的原因是未来的读者可以从这个问题中受益并快速了解它的要点。我觉得编辑将使未来的读者受益。 @HoomanBahreini 您最初的问题是:“我不明白的是,提供者首先是如何传递给操作方法的?为什么禁用按钮会阻止提供者被传递”。这与询问哪些控件提交数据非常不同。 【参考方案1】:

我先回答这个问题:

我不明白的是,首先provider是如何传递给action方法的?

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

下一步:

为什么禁用按钮会阻止提供者被传入?

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

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

希望这会有所帮助。

更新

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

    &lt;input&gt; &lt;button&gt; &lt;option&gt;

【讨论】:

非常感谢您的回答。是的,这就是我的困惑......我认为表单帖子中只包含输入字段,但您是说按钮值也包含在回帖中?您是否知道任何解释回发中包含哪些字段的参考文档? 顺便说一句,我更新了问题并删除了 jQuery 代码以强调主要问题,即提交中包含表单字段的标准? 我已更新我的答案以显示表单数据中包含哪些字段【参考方案2】:

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

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

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

HTML 定义了以下控件类型:

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

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

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

https://www.w3.org/TR/html4/interact/forms.html#h-17.2.1 https://www.w3.org/TR/html5/sec-forms.html#submittable-element

【讨论】:

以上是关于提交按钮是不是在表单提交时将其值传递给操作方法?的主要内容,如果未能解决你的问题,请参考以下文章

Django,如何在提交表单时将 HTML 表单值传递给 URL?

如何在表单提交时将 HTML 标签值传递给 PageModel

提交表单时将选定对象 ID 的列表传递给控制器

启用/禁用表单提交按钮不起作用

单击单选按钮时,将其值传递给 vue 组件实例

在JSP中没有表单,怎么用按钮(button)将数据提交给某个url,请教这个JS方法怎么写?