提交按钮是否在表单提交时将其值传递给操作方法?
提交按钮是否在表单提交时将其值传递给操作方法?
更新:
当表单提交后,哪些控件/字段的值会被提交?
在 ASP.NET MVC 表单中,如果用户双击提交按钮,表单将被提交两次。为了解决这个问题,我实现了解决方案,解释在这里。这是我的解决方案,在表单提交时禁用提交按钮,以防止再次点击:
function preventFromBeingDoubleSubmitted() { $('form').each(function () { $(this).submit(function (e) { if ($("form").valid()) { // 如果表单有效,则禁用提交按钮,防止双击(双重提交) $(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()
@foreach (AuthenticationDescription p in loginProviders.OrderBy(o => o.Caption))
{
if (string.Equals(p.AuthenticationType, "google", StringComparison.InvariantCultureIgnoreCase))
{
}
if (string.Equals(p.AuthenticationType, "facebook", StringComparison.InvariantCultureIgnoreCase))
{
}
}
}
}
}
上述代码应该触发以下控制器动作(内置的身份模板):
[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
动作方法中,一切正常。
我不明白的是,提供者是如何传递到动作方法中的?为什么禁用按钮会阻止提供者被传递?
HTML表单是文档的一部分,包含普通内容、标记、特殊元素(复选框、单选按钮、菜单等)以及这些控件的标签。用户通常通过修改控件(输入文本、选择菜单项等)来“完成”表单,然后将表单提交给处理代理(例如Web服务器、邮件服务器等)进行处理。
用户通过命名控件与表单交互。
控件的“控件名称”由其name属性给出。控件的name属性在FORM元素内的范围是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/html4/interact/forms.html#h-17.2.1)
- [https://www.w3.org/TR/html5/sec-forms.html#submittable-element](https://www.w3.org/TR/html5/sec-forms.html#submittable-element)
问题的出现原因是由于HTML规范中规定了按钮作为控件的特性,其值会在提交表单时传递给服务器。解决方法是可以参考HTML规范中关于控件的定义和行为。
问题的出现原因是:按钮的值没有被传递到action方法中。解决方法是:隐藏按钮而不是禁用它,这样在表单提交时,按钮的值就会被传递到服务器中。
在这个问题中,按钮的值是通过name="provider" value=".AuthenticationType"
这段代码传递到action方法中的。
当表单被提交时,禁用的字段的值不会被传递到服务器中,这是默认行为。所以我们可以通过隐藏按钮而不是禁用它来解决这个问题。在preventFromBeingDoubleSubmitted()
中,将$(this).find(':submit').attr('disabled', 'disabled');
改为$(this).find(':submit').hide();
即可解决。
另外,关于哪些字段会被包含在表单数据中的新问题,以下是会被包含的字段:
<input>
<button>
<option>
希望这些解答能对你有所帮助。