41

I have a basic form for which I want to handle buttons inside the form by calling the ActionResult method in the View's associated Controller class. Here is the following HTML5 code for the form:

<h2>Welcome</h2>

<div>

    <h3>Login</h3>

    <form method="post" action= <!-- what goes here --> >
        Username: <input type="text" name="username" /> <br />
        Password: <input type="text" name="password" /> <br />
        <input type="submit" value="Login">
        <input type="submit" value="Create Account"/>
    </form>

</div>

<!-- more code ... -->

The corresponding Controller code is the following:

[HttpPost]
public ActionResult MyAction(string input, FormCollection collection)
{
    switch (input)
    {
        case "Login":
            // do some stuff...
            break;
        case "Create Account"
            // do some other stuff...
            break;
    }

    return View();
}
tereško
  • 58,060
  • 25
  • 98
  • 150
dtg
  • 1,803
  • 4
  • 30
  • 44

2 Answers2

90

you make the use of the HTML Helper and have

    @using(Html.BeginForm())
    {
        Username: <input type="text" name="username" /> <br />
        Password: <input type="text" name="password" /> <br />
        <input type="submit" value="Login">
        <input type="submit" value="Create Account"/>
    }

or use the Url helper

<form method="post" action="@Url.Action("MyAction", "MyController")" >

Html.BeginForm has several (13) overrides where you can specify more information, for example, a normal use when uploading files is using:

@using(Html.BeginForm("myaction", "mycontroller", FormMethod.Post, new {enctype = "multipart/form-data"}))
{
    < ... >
}

If you don't specify any arguments, the Html.BeginForm() will create a POST form that points to your current controller and current action. As an example, let's say you have a controller called Posts and an action called Delete

public ActionResult Delete(int id)
{
   var model = db.GetPostById(id);
   return View(model);
}

[HttpPost]
public ActionResult Delete(int id)
{
    var model = db.GetPostById(id);
    if(model != null) 
        db.DeletePost(id);

    return RedirectToView("Index");
}

and your html page would be something like:

<h2>Are you sure you want to delete?</h2>
<p>The Post named <strong>@Model.Title</strong> will be deleted.</p>

@using(Html.BeginForm())
{
    <input type="submit" class="btn btn-danger" value="Delete Post"/>
    <text>or</text>
    @Url.ActionLink("go to list", "Index")
}
Drenmi
  • 8,492
  • 4
  • 42
  • 51
balexandre
  • 73,608
  • 45
  • 233
  • 342
  • 1
    I attempted method 2 with the URL helper, but I think the syntax I found was MVC3 specific and it did not work. This one suited my needs perfectly. Thank you! – dtg Mar 03 '13 at 21:19
  • @Dylan : Because there is missing ) bracket in Html.BeginForm line. – Muflix Oct 26 '15 at 08:07
  • 1
    How did you have both `public ActionResult Delete(int id)` and `[HttpPost] public ActionResult Delete(int id)`? Isn't there a name collision between the two? – Alexander Jul 15 '16 at 15:32
  • Thanks for a really complete answer explaining common overloads :) – JamieS Sep 16 '16 at 19:19
  • 1
    @AlexanderMomchliov the `[HttpPost]` above the action result lets razor know that the actionresult is the specified one for post. so it will know which one to take depending on the method used to call it – maam27 Nov 10 '16 at 09:53
0

Here I'm basically wrapping a button in a link. The advantage is that you can post to different action methods in the same form.

<a href="Controller/ActionMethod">
    <input type="button" value="Click Me" />
</a>

Adding parameters:

<a href="Controller/ActionMethod?userName=ted">
    <input type="button" value="Click Me" />
</a>

Adding parameters from a non-enumerated Model:

<a href="Controller/ActionMethod?userName=@Model.UserName">
    <input type="button" value="Click Me" />
</a>

You can do the same for an enumerated Model too. You would just have to reference a single entity first. Happy Coding!

jade290
  • 413
  • 6
  • 5