Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 - Understanding POST with a button

How does one obtain the form data after submitting it?

<form target="_self" runat="server">
    <p>
    <select id="BLAHBLAH2">
        <option>2010</option>
        <option>2011</option>
        <option>2012</option>
        <option>2013</option>
    </select>
    <input type="submit" runat="server" value="Change Year" />
    </p>
</form>

This hits the controller's Index method. But, there's nothing in Request.Form. Why?

Second, can I use

<input type="button" instead of type=submit? That is, without introducing ajax via onclick.

Finally, how do I submit to a different method in the controller, e.g. Create?

like image 738
P.Brian.Mackey Avatar asked Oct 07 '11 20:10

P.Brian.Mackey


2 Answers

Try removing those runat server tags. They should not be used in ASP.NET MVC. Also your select doesn't have a name. If an input element doesn't have a name it won't submit anything. Also your option tags must have value attributes which indicates what value will be sent to the server if this options is selected:

<form action="/Home/Create" method="post">
    <p>
    <select id="BLAHBLAH2" name="BLAHBLAH2">
        <option value="2010">2010</option>
        <option value="2011">2011</option>
        <option value="2012">2012</option>
        <option value="2013">2013</option>
    </select>
    <input type="submit" value="Change Year" />
    </p>
</form>

But the correct way to generate forms in ASP.NET MVC is to use HTML helpers. Depending on the view engine you are using the syntax might be different. Here's an example with the Razor view engine:

@model MyViewModel
@using (Html.BeginForm("Create", "Home")) 
{
    <p>
        @Html.DropDownListFor(x => x.SelectedYear, Model.Years)
        <input type="submit" value="Change Year" />
    </p>
}

Here you have a strongly typed view to some given view model:

public class MyViewModel
{
    public string SelectedYear { get; set; }

    public IEnumerable<SelectListItem> Years
    {
        get
        {
            return Enumerable
                .Range(2010, 4)
                .Select(x => new SelectListItem
                {
                    Value = x.ToString(),
                    Text = x.ToString()
                });
        }
    }
}

which is populated by some controller action that will render this view:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();
        return View(model);
    }

    [HttpPost]
    public ActionResult Create(MyViewModel model)
    {
        ... model.SelectedYear will contain the selected year
    }
}
like image 192
Darin Dimitrov Avatar answered Nov 15 '22 22:11

Darin Dimitrov


None of your <option> tags have a value:

...
<option value="2010">2010</option>
...

As noted by David, runat="server" is most definitely a WebForms thing, so you can 86 that.

If you want to submit to a different method on your controller you just need to specify the URL for that method.

Easy way using Html.BeginForm:

@using (Html.BeginForm("AnotherAction", "ControllerName")) {
   <!-- Your magic form here -->
}

Using Url.Action

<form action="@Url.Action("AnotherAction")" method="POST">
   <!-- Your magic form here -->
</form>
like image 23
Josh Avatar answered Nov 15 '22 22:11

Josh