0

I am in the middle of learning MVC and it's such a different way of thinking, I have taken a simple login form as an example but the one thing that confuses me is how I tie up the submit button to the Action and pass the object. Let me give you the example.

Here is the Model

public class ExternalUser
    {

        [Display(Name = "User Name")]
        [MaxLength(50)]
        public string UserName { get; set; }
        [Display(Name = "Password")]

        public string Password { get; set; }
        [Display(Name = "Remember Me")]

        public bool RememberMe { get; set; }
        public bool IsValid()
        {
            return true;
        }
    }

Here is the View

@model ExternalUser
@{
    ViewBag.Title = "Login";    
}
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true, "Login failed. Check your login details.");
    <div>
        <fieldset>
            <legend>Login</legend>
            <div class="editor-label">
                @Html.LabelFor(u => u.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(u => u.UserName)
                @Html.ValidationMessageFor(u => u.UserName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(u => u.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(u => u.Password)
                @Html.ValidationMessageFor(u => u.Password)
            </div>
            <div class="editor-label">
                @Html.CheckBoxFor(u => u.RememberMe)
                @Html.LabelFor(u => u.RememberMe)
            </div>
            <input type="submit" value="Log In" />
        </fieldset>
    </div>
}

Here is the Controller

 public class UserController : Controller
    {
        // GET: /User/
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Login(ExternalUser user)
        {
            if (ModelState.IsValid)
            {
                if (user.IsValid())
                {
                    FormsAuthentication.SetAuthCookie(user.UserName, user.RememberMe);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", "Login data is incorrect!");
                }
            }
            return View(user);
        }
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }
    }

When I click the Login button, it's going to the first overload of public ActionResult Login() and not the Second overload of public ActionResult Login(ExternalUser user) which is what I would expect, can you tell me what I'm missing as to why it's not hitting the correct method?

Thanks

6
  • 4
    Are you very sure about that ? Your code should work fine. It should submit the data to your HttpPost Login method. How do you know that it is going to the first action? Did you put a breakpoint in your action method(s) and verify it ? Commented Aug 2, 2016 at 16:08
  • Is your form somehow issuing a GET request instead of a POST request? What is the actual form tag? When you monitor the request in your browser's debugging tools, what type of request is it? Does it contain the data you expect? How specifically are you confirming the behavior you're seeing? Commented Aug 2, 2016 at 16:15
  • @shyju that's exactly what I did. The breakpoint confirmed that it was going to the wrong method Commented Aug 2, 2016 at 17:35
  • What is the form tag method generated ? does it explicitly says it is GET ? Commented Aug 2, 2016 at 17:38
  • That's one thing I need to check but I can't do that right now. I will get back to you. I'm pretty sure it's a get because the url was returning the variables in the querystring Commented Aug 2, 2016 at 17:52

2 Answers 2

4

Can't think of a reason why it would not work. But, none the less check the HTML generated in the browser using inspect element option. If the <form> tag has action attribute value set to 'GET' or if the action attribute is missing altogether, try explicitly specifying it as post.

Html.BeginForm("Login", "User", FormMethod.Post)
Sign up to request clarification or add additional context in comments.

2 Comments

This is what I was going to write.
I checked the HTML it's already set to POST <form action="/user/login" method="post">
0

I realised that I had put in an extra <form> tag in the /Shared/SiteLayout.cshtml, therefore causing two <forms> to placed on the page, after removing the one in the shared folder it now fires the right method! I hope this helps someone in the future.

2 Comments

That is interesting. Just curious, so was the login form wrapped inside the form in SiteLayout.cshtml? like below ``` <form> --sitelayout.cshtml <form> --login.cshtml <input type="submit" /> </form> </form> ```
essentially yes, that was the problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.