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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With