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?