提交按钮是否将其值传递给操作方法,在表单提交上? [英] Does submit button passes its value to action method, on form submit?

查看:167
本文介绍了提交按钮是否将其值传递给操作方法,在表单提交上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:

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


在ASP.NET MVC表单中,如果用户双击提交"按钮,则该表单将被提交两次.为了解决此问题,我实施了

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>
        }
    }
}

以上代码,应点击以下控制器操作"(内置身份模板):

[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 Action方法传递,并且一切正常.

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

解决方案

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

用户通过命名控件与表单进行交互.

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

HTML定义了以下控件类型:

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

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

您可以参考这些链接以获取更多详细信息

Update:

What are the control/fields whose value would be submitted when the form is post back?


In an ASP.NET MVC Form, if user double clicks on the submit button, the form would be submitted two times. In order to solve this problem I implemented the solution explained here.

This is my solution, where I disable the submit button on form submit so it cannot be clicked again:

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

This works fine, but I am getting a very strange behavior with ASP.NET Built in, Identity code. My login page, allows user to login with Facebook or Google (each of those buttons are submit buttons):

This is the code which generates the above login form (this is the built-in identity template):

@{
    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>
        }
    }
}

The above code, should hit the following Controller Action (built-in identity template):

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

After, adding the .js code to prevent double submission, the external login no longer works. The problem is, when user clicks on Log in with Facebook button, the provider name is no longer passed in to ExternalLogin Action.

If I remove preventFromBeingDoubleSubmitted() function, provider name would be passed in ExternalLogin Action method and everything works fine.

What I don't understand is, how is provider passed in to action method at the first place? And why disabling the button prevents provider from being passed in?

解决方案

An HTML form is a section of a document containing normal content, markup, special elements called controls (checkboxes, radio buttons, menus, etc.), and labels on those controls. Users generally "complete" a form by modifying its controls (entering text, selecting menu items, etc.), before submitting the form to an agent for processing (e.g., to a Web server, to a mail server, etc.)

Users interact with forms through named controls.

A control's "control name" is given by its name attribute. The scope of the name attribute for a control within a FORM element is the FORM element.

HTML defines the following control types:

  • buttons
  • checkboxes
  • radio buttons
  • menus: Menus offer users options from which to choose. The SELECT element creates a menu, in combination with the OPTGROUP and OPTION elements.
  • input controls (number, text, etc.)
  • hidden controls
  • object controls: Authors may insert generic objects in forms such that associated values are submitted along with other controls. Authors create object controls with the OBJECT element.

Because buttons are controls so the button's value will be posted to the server (if the buttons have name and value like your example). So it is about html specification. NOT asp.net mvc, not Microsoft's specification

You can refer these links for more details

这篇关于提交按钮是否将其值传递给操作方法,在表单提交上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆