1

How does MVC handle the submit button in my code? I have a controller named ArticleController which should handle it, but I can't figure out how.

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Article</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Text, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Text, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Text, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default"/>
        </div>
    </div>
</div>
}

<div>
  @Html.ActionLink("Back to List", "Index")
</div>

The controller looks like this:

namespace Decision.Controllers
{
  public class ArticleController : Controller
  {
    // GET: Article
    public ActionResult Index()
    {
        return View();
    }
    [HttpGet]
    public ActionResult Create()
    {
        var article = new ArticleController();
        var home = new HomeController();
        return View(home);
    }

    /*[HttpPost]
    public ActionResult Create(Article article)
    {
        entities.Article.AddObject(article);
        entities.SaveChanges();

        return Redirect("/");
    }*/
  }
}

Which method handles the submit button when clicked?

Fenrir
  • 231
  • 2
  • 18
  • 1
    Your controller need a `Index()` method marked with `[HttpPost]` and it should include a parameter for the model you use in the view (which will be bound with the values of the form controls (and as a side note, the code in your `Create()` GET method makes no sense - you do not initialize instances of the controllers) –  Feb 07 '17 at 09:38
  • Just use `@using (Html.BeginForm("Create", "Article", FormMethod.Post))` and `[HttpPost]` in second `Create` method. You don't need to handle submit button click event, the form automatically call the controller action method given in context. – Tetsuya Yamamoto Feb 07 '17 at 09:39
  • Well, if you remove verb filter and make `article` an optional parameter `public ActionResult Create(Article article = null)` then you can use this method for both `get` and `post` requests. You can check iif article is `null` then return View, and if it is not - proceed with BL to save it. But this is rather an unusual way of working with MVC controller. – Fabjan Feb 07 '17 at 09:41

4 Answers4

1

The HttpPost controller normally handles it but you have that commented out for some reason? You need to mark you BeignForm with some information i.e.

@using (Html.BeginForm("Create", "Article", FormMethod.Post, new { @class = "insert any css class here", role = "form" }))
{ 
Bad Dub
  • 1,503
  • 2
  • 22
  • 52
  • it didnt work together with the httpget. In an article i looked at they used both but in my code they both dont go along with eachother, so my httppost would handle the button? – Fenrir Feb 07 '17 at 09:37
  • Try to update your begin form to something like the edited answer. – Bad Dub Feb 07 '17 at 09:44
  • The application searches for a site called Create that it doesnt find when I press the button. How do I call the function Create inside the Controller. – Fenrir Feb 07 '17 at 10:46
  • Try taking the Value = "Create" out of your submit button. Also make sure your HttpPost is not commented out – Bad Dub Feb 07 '17 at 10:49
  • It goes into the HttpPost method, How can I get the EditorFor Text? And is it usual to open the context in that httppost method to write the data into the database or how do you usually do it? – Fenrir Feb 07 '17 at 11:08
  • I would normally do everything using the MVC format. So the context would never be exposed in the controller. It would be called in a repository. – Bad Dub Feb 07 '17 at 11:16
1

So, in pure HTML you need to have a submit button inside a form that has post method.

 <form action = "" method = "post">
        <input type="submit" name="x" value="x" />
 </form>

BeginForm extension uses by default the post method.

public static MvcForm BeginForm(
    this HtmlHelper htmlHelper
)

To understand how to use BeginForm extension you can read more here: How does @Html.BeginForm() works?

Your main problem looks to be the following:

to understand how @using (Html.BeginForm()) works, you need to know what page it is already on . using @using (Html.BeginForm()) in 2 different views will come back to two different controllers

First you can check what action gets generated in your HTML when you render the form: <form action = "" method = "post">.

Then you must know that you have the possibility to pass the executed action/controller to BeginForm extension method.

For example:

@using (Html.BeginForm("Create", "Article", FormMethod.Post))
{
  @* *@ 
}
Community
  • 1
  • 1
Razvan Dumitru
  • 11,815
  • 5
  • 34
  • 54
1

please have a look at https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods for a clear idea about request methods.

When a user views a page, that's a GET request and when a user submits a form, that's usually a POST request. HttpGet and HttpPost just restrict the action to the applicable request type.

When you add [HttpPost] to the action, MVC clearly knows which action to use to handle POST request.

Bits_Please
  • 546
  • 1
  • 5
  • 13
0

Seems like you are in index view. You need to change BeginForm to

@using (Html.BeginForm("Create","Article")) 
{
    <<your stuff>>
}

and uncomment post method.

Imad
  • 7,126
  • 12
  • 55
  • 112