Sampath
Sampath

Reputation: 65860

Wrong hidden filed value is being passed to the Action Method

Update :

This is an SPA app.So it's having js file also for supporting the submit button.So I think problem is on it.Could you tell me how to modify it to support multiple kind of submit buttons ? At this moment I think it supports only for a single submit button.That is why it always get the first form's hidden field value I think.Thanks.

JS

 var $loginForm = $('.login-form');

 $loginForm.submit(function (e) {
            e.preventDefault();

            if (!$('.login-form').valid()) {
                return;
            }

            abp.ui.setBusy(
                null,
                abp.ajax({
                    contentType: app.consts.contentTypes.formUrlencoded,
                    url: $loginForm.attr('action'),
                    data: $loginForm.serialize()
                })
            );
        });

UI

enter image description here

VM

 public class LoginViewModel
    {
        public string TenancyName { get; set; }

        [Required]
        public string UsernameOrEmailAddress { get; set; }

        [Required]
        public string Password { get; set; }

        public bool RememberMe { get; set; }
    }

CompanyLoginFormViewModel VM :

 public class CompanyLoginFormViewModel
    {
        public LoginViewModel LoginViewModel { get; set; }

        public List<TenantListDto> Tenants { get; set; }

    }

*.cshtml page

@{
    var companyLoginFormViewModel = TempData["CompanyLoginFormViewModel"] as CompanyLoginFormViewModel;
} 

    @foreach (var tenant in companyLoginFormViewModel.Tenants)
                {
                    <form class="login-form" action="@Url.Action("Login")[email protected]" name="companyLoginForm" method="post">
    <input type="hidden" name="usernameOrEmailAddress" value="@companyLoginFormViewModel.LoginViewModel.UsernameOrEmailAddress" />
                <input type="hidden" name="password" value="@companyLoginFormViewModel.LoginViewModel.Password" />
                       <input type="hidden" name="rememberMe" value="true" />
                        <input type="hidden" name="companyUrl" value="true" />
                        <input type="hidden" name="tenancyName" value="@tenant.TenancyName" />

                        <div class="row margin-top-10">
                            <div class="col-xs-3">
                                <button type="submit" class="btn btn-success uppercase">@L("LogIn")</button>
                            </div>
                           </div>
                    </form>
                }

Generated html

     <form class="login-form" action="/Account/Login?returnUrl=/Application" name="companyLoginForm" method="post" novalidate="novalidate">
         <input type="hidden" name="usernameOrEmailAddress" value="[email protected]">
          <input type="hidden" name="password" value="fake">
            <input type="hidden" name="rememberMe" value="true">
            <input type="hidden" name="companyUrl" value="true">
            <input type="hidden" name="tenancyName" value="Asset_Management">

            <div class="row margin-top-10">
                <div class="col-xs-3">
                    <button type="submit" class="btn btn-success uppercase">Log in</button>
                </div>
            </div>
        </form>
        <form class="login-form" action="/Account/Login?returnUrl=/Application" name="companyLoginForm" method="post" novalidate="novalidate">
    <input type="hidden" name="usernameOrEmailAddress" value="[email protected]">
            <input type="hidden" name="password" value="fake">
            <input type="hidden" name="rememberMe" value="true">
            <input type="hidden" name="companyUrl" value="true">
            <input type="hidden" name="tenancyName" value="Associates">

            <div class="row margin-top-10">
                <div class="col-xs-3">
                    <button type="submit" class="btn btn-success uppercase">Log in</button>
                </div>
               </div>
        </form>
        <form class="login-form" action="/Account/Login?returnUrl=/Application" name="companyLoginForm" method="post" novalidate="novalidate">
<input type="hidden" name="usernameOrEmailAddress" value="[email protected]">
        <input type="hidden" name="password" value="fake">
            <input type="hidden" name="rememberMe" value="true">
            <input type="hidden" name="companyUrl" value="true">
            <input type="hidden" name="tenancyName" value="ALL">

            <div class="row margin-top-10">
                <div class="col-xs-3">
                    <button type="submit" class="btn btn-success uppercase">Log in</button>
                </div>
            </div>
        </form>

Post method

 [HttpPost]      
    public virtual async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "", bool companyUrl = false)
   {
             CheckModelState();
            // removed for clarity
    }

Question : Even though I have press the 2nd submit button,it always send the tenancyName as first submit button's value.That is Asset_Management.Could you tell me why ? Thanks.

Upvotes: 0

Views: 122

Answers (2)

user3559349
user3559349

Reputation:

Your problem is with the script.

var $loginForm = $('.login-form');

is a collection of all your forms, but

data: $loginForm.serialize(),

will only serialize the first one, so you always posting the vales of the first form. Modify the script to handle the buttons .click() event and get its associated form

$('.btn-success').click(function(e) { 
    e.preventDefault(); // if you makes the button type="button" this is not required
    var form = $(this).closest('.login-form');
    if (!form.valid()) {
        return;
    }
    abp.ui.setBusy(
        null,
        abp.ajax({
            contentType: app.consts.contentTypes.formUrlencoded,
            url: form.attr('action'),
            data: form.serialize()
        })
    );
});

Upvotes: 1

FailedUnitTest
FailedUnitTest

Reputation: 1800

Why do you even have <form> and <button> at all? Why not create links in your foreach loop, something like this:

@Html.ActionLink("Login for " + tenant.Name, "LoginAction", new {Id=tenant.Id})

You can style these links all blue and pretty as you like using CSS afterwards.

Update1, you can pass parameters to your controller using the anonymous object. Do you see how I am passing Id? Your Action will need to accept id, see this answer: passing multiple parameters in @html.actionlink()

Update2, passing username and password like this is very bad practice. You are exposing secure credentials to the view. You should forward the user to the login page with username + password input boxes where the user will login.

Upvotes: 1

Related Questions