Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Form not posting, calling GET

I can't get my form to call the POST action on my controller.

My page code

@model My.Models.ManageUserViewModel

@using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @id = "manageAccountFormHolder", @class = "form-horizontal col-sm-8 col-sm-offset-2 v-offset-4" }))
    {
        @Html.AntiForgeryToken()
        <h4 class="text-center">Change Password</h4>

        <div class="form-group">
            @Html.LabelFor(m => m.OldPassword, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.NewPassword, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
            </div>
        </div>

        <h4 class="text-center v-offset-4">Edit Personal Details</h4>

        <div class="form-group">
            @Html.LabelFor(m => m.FirstName, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-4">
                @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control", @placeholder = "First name" })
            </div>
            <div class="col-sm-5">
                @Html.TextBoxFor(m => m.LastName, new { @class = "form-control", @placeholder = "Last name" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.Mobile, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                <input class="form-control" id="manageMobile" name="manageMobile" type="tel">
                @Html.TextBoxFor(m => m.Mobile, new { @class = "form-control", @placeholder = "First name" })
                <p class="help-block">For authorisation code. We will never share or display your mobile number.</p>
            </div>
        </div>

        <h4 class="text-center v-offset-4">Edit Address</h4>

        <div class="form-group">
            @Html.LabelFor(m => m.Address1, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-2">
                @Html.TextBoxFor(m => m.Address1, new { @class = "form-control"})
            </div>
            <div class="col-sm-7">
                @Html.TextBoxFor(m => m.Address2, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.TownSuburb, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.TextBoxFor(m => m.TownSuburb, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.StateRegion, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.TextBoxFor(m => m.StateRegion, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.PostCode, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.TextBoxFor(m => m.PostCode, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.Country, new { @class = "col-sm-3 control-label" })
            <div class="col-sm-9">
                @Html.TextBoxFor(m => m.Country, new { @class = "form-control" })
                @Html.HiddenFor(m => m.CountryIso, new { @class = "form-control" })
            </div>
        </div>

        <div class="text-center">
            <button class="btn btn-default" type="submit">Save Changes</button>
        </div>
    }

My Model

public class ManageUserViewModel
{
    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Current password")]
    public string OldPassword { get; set; }

    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm New Password")]
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    [Required]
    [Display(Name = "Full Name")]
    public string FirstName { get; set; }

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

    [Required]
    [Display(Name = "Mobile Number")]
    public string Mobile { get; set; }

    [Display(Name = "Street Address")]
    public string Address1 { get; set; }

    public string Address2 { get; set; }

    [Display(Name = "City")]
    public string TownSuburb { get; set; }

    [Display(Name = "State")]
    public string StateRegion { get; set; }

    [Display(Name = "Postcode")]
    public string PostCode { get; set; }

    [Display(Name = "Country")]
    public string Country { get; set; }

    public string CountryIso { get; set; }
}

My Controller actions

[HttpGet]
public ActionResult Manage(ManageMessageId? message)
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Manage(ManageUserViewModel model)
{
    //Save changes code here
    //Redirect
}

It won't validate either. If I leave one of the required fields blank, no validation error shows.

In Fiddler, I see that the form is posting to the server, but the GET method is still called? See Fiddler raw below, this still calls the GET method (I updated my model to only one property to make it simpler).

POST https://localhost:44301/Account/Manage HTTP/1.1
Host: localhost:44301
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://localhost:44301/account/manage
Cookie: __RequestVerificationToken=xxxx..........
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 20

OldPassword=dfgdfgdg
like image 420
garethb Avatar asked Dec 20 '22 05:12

garethb


2 Answers

It's fixed! If anyone can tell me why because I have NFI.......

Changing this line

@using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @id = "manageAccountFormHolder", @class = "form-horizontal col-sm-8 col-sm-offset-2 v-offset-4" }))

to

@using (Html.BeginForm())

and I'm posting again. Yey, coding genius, 4 hours to post a form! Anyone want to hire me for a job?

EDIT:

So after further digging, the issue was that we had implemented lower case routes. Since the route was being rewritten from /Account/Manage to /account/manage, the post action is never found (finds the get action fine though). Html.BeginForm() was rendering the action in lowercase, whereas Html.BeginForm("Manage", "Account", FormMethod.Post, new{}) wasn't since I specified camel case for the action and controller.

like image 130
garethb Avatar answered Jan 06 '23 12:01

garethb


Change your button to input

<input class="btn btn-default" type="submit" value="Save Changes" />
like image 22
Mairaj Ahmad Avatar answered Jan 06 '23 13:01

Mairaj Ahmad