Reputation: 759
I've just begun learning ASP MVC 4, and I'm working on a basic exercise, which is a book hosting website.
I'm currently working on a controller for adding a new book to the repository. The view for the appropriate action is strongly-typed to the Book
class as its model. Book
is a very simple model consisting of title, author and so forth.
My AddBook
controller currently looks like this: (I haven't implemented any database insertion logic on POST, yet)
public class AddBookController : Controller
{
[HttpGet]
public ActionResult AddBook()
{
return View();
}
[HttpPost]
public ActionResult AddBook(Book book)
{
return View();
}
}
My view is also very simple:
@model Bookshare.Models.Book
@{
ViewBag.Title = "AddBook";
}
Add a new book
@using (Html.BeginForm())
{
Html.TextBoxFor(model => model.Title);
Html.TextBoxFor(model => model.Author);
Html.TextBoxFor(model => model.PublishingCompany);
Html.TextBoxFor(model => model.ReleaseYear);
Html.TextBoxFor(model => model.Summary);
}
And yet, when I call this action, all I can see is the "Add a new book" header and the submit button for the form. No text boxes whatsoever. This also happens if I use the plain old Html.TextBox
syntax. Viewing the page's source reveals just an empty form tag.
What am I doing wrong here?
Upvotes: 3
Views: 2501
Reputation: 9145
The way you are using the Html Helper is wrong. The TextBoxFor
method is not a void method that you call like Html.TextBoxFor(...);
. It returns an MvcHtmlString
object that you want to write on the page. Therefore, you use it like below:
@Html.TextBoxFor(model => model.Title)
@
in the above code is the equivalent of Response.Write
in classic asp.
So, your Form in its simplest way should be like this:
@using (Html.BeginForm())
{
@Html.TextBoxFor(model => model.Title)
@Html.TextBoxFor(model => model.Author)
@Html.TextBoxFor(model => model.PublishingCompany)
@Html.TextBoxFor(model => model.ReleaseYear)
@Html.TextBoxFor(model => model.Summary)
}
But, that will render all TextBoxes next to each other without a Label, and without a placeholder for validation message. Replace each TextBox in your View with something like below to format them on the page properly and to add a Label and a Validation Message placeholder.
<div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
EditorFor
will be rendered as TextBox for string properties.
Upvotes: 4
Reputation: 11492
It turns out that for the correct form you need only the following. The controller for the create method can be like this:
public ActionResult Create()
{
return View();
}
My working view looks like this, your fields of course will be slightly different:
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Book</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Author)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Author)
@Html.ValidationMessageFor(model => model.Author)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
With this I can see the form rendered in the browser.
Upvotes: 2