5

I am new to asp.net mvc. with this reference this. i am using Tuples to send two models in to one view. i am creating two forms and two submit buttons ; but values are coming to null when it the server

@model Tuple<DAL.Models.LoginModel, DAL.Models.ForgotPassword>

@{ ViewBag.Title = "Login"; }

@using (Html.BeginForm("Login", "User", FormMethod.Post, new { ReturnUrl = ViewBag.ReturnUrl }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>

        <ol>
            <li>
                @Html.LabelFor(m => m.Item1.EmailID)
                @Html.TextBoxFor(m => m.Item1.EmailID, new { @id = "txt_login_EmailID" })
                @Html.ValidationMessageFor(m => m.Item1.EmailID)
            </li>
            <li>
                @Html.LabelFor(m => m.Item1.Password)
                @Html.PasswordFor(m => m.Item1.Password)
                @Html.ValidationMessageFor(m => m.Item1.Password)
            </li>

            <li>
                <input type="submit" value="Login" id="btn_login" />

                @Html.CheckBoxFor(m => m.Item1.RememberMe)
                @Html.LabelFor(m => m.Item1.RememberMe, new { @class = "checkbox" })
            </li>
        </ol>

    </fieldset>
}

this another form in the same page

  @using (Html.BeginForm("ForgotPassword", "user"))

   {

    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>

        <ol>
            <li>
                @Html.LabelFor(m => m.Item2.EmailId)
                @Html.TextBoxFor(m => m.Item2.EmailId, new { @id = "txt_fg_pwd_EmailID" })
                @Html.ValidationMessageFor(m => m.Item2.EmailId)

            </li>
            <li>

                <input type="submit" value="Reset Password" />
            </li>
        </ol>
    </fieldset>
}

my post method is

    [HttpPost]
    public ActionResult Login(LoginModel LoginUser , string returnUrl)
    {   


        if (LoginUser.IsValid)
        {

            SetAuthenticationCookie(LoginUser, LoginUser.RememberMe);

            return RedirectToLocal(returnUrl);

        }
        else
        {
            ModelState.AddModelError("", "Incorrect user name or password .");
            return View(LoginUser);
        }


    }

`

Any changes need to to view or post method

Community
  • 1
  • 1
Kartheek
  • 281
  • 1
  • 6
  • 21

2 Answers2

23

Try like this:

[HttpPost]
public ActionResult Login([Bind(Prefix = "Item1")] LoginModel loginUser, string returnUrl)
{
    ...
}

Since your values are prefixed with Item1 you should indicate that to the model binder. Of course the same stands true for your ForgotPassword action:

[HttpPost]
public ActionResult ForgotPassword([Bind(Prefix = "Item2")] ForgotPassword model)
{
    ...
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • It is working fine now. but i want to know why the values becoming null – Kartheek May 29 '13 at 15:20
  • 3
    Because your input field is named `name="Item1.EmailID"`? Notice the `Item1` prefix? That's because of the helper you used: `@Html.TextBoxFor(m => m.Item1.EmailID, new { @id = "txt_login_EmailID" })`. But your `LoginModel` doesn't have a property called `Item1.EmailID`. It has a property called `EmailID`. Unfortunately in the POST request payload there's no such value being sent and the default model binder has no way of knowing (unless you tell him) that he should bind the `Item1.EmailID` value from the request body to the `EmailID` property of your model. The model binder works by convention – Darin Dimitrov May 29 '13 at 15:23
  • @DarinDimitrov Thank you – Amir978 Jun 26 '18 at 03:53
1

This is the wrong way to go about this. Use child actions:

Controller

[ChildActionOnly]
public ActionResult LoginForm(string returnUrl)
{
    ViewBag.returnUrl = returnUrl;
    return View(new LoginModel());
}

[ChildActionOnly]
public ActionResult ForgotPasswordForm(string returnUrl)
{
    ViewBag.returnUrl = returnUrl;
    return View(new ForgotPassword());
}

Then you create a view for each one (where you'll just copy in your existing form view code for each. Just remember to set the proper model for the view and turn off the layout:

LoginForm.cshtml

@model DAL.Models.LoginModel
@{ Layout = null; }

<!-- Form code here -->

ForgoutPasswordForm.cshtml

@model DAL.Models.ForgotPassword
@{ Layout = null; }

<!-- Form code here -->

And, finally, in your original view:

@{ Html.RenderAction("LoginForm", new { returnUrl = ViewBag.returnUrl }); }

@{ Html.RenderAction("ForgotPasswordForm", new { returnUrl = ViewBag.returnUrl }); }
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444