Modifying the Index view
One of the problems with the Index view that was generated for us was that it displayed the random key, password, and hashed password.
This is actually quite easy to modify. We just remove the fields we don't want from the view. Just delete the <td> and </td> tags the code between for the offending fields. Here is the code for the revised view.
@model IEnumerable<BookReviewMVCApp.Models.Reviewer> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.ReviewerUserName) </th> <th> @Html.DisplayNameFor(model => model.ReviewerFirstName) </th> <th> @Html.DisplayNameFor(model => model.ReviewerLastName) </th> <th> @Html.DisplayNameFor(model => model.ReviewerEmail) </th> <th> @Html.DisplayNameFor(model => model.ReviewerDateEntered) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.ReviewerUserName) </td> <td> @Html.DisplayFor(modelItem => item.ReviewerFirstName) </td> <td> @Html.DisplayFor(modelItem => item.ReviewerLastName) </td> <td> @Html.DisplayFor(modelItem => item.ReviewerEmail) </td> <td> @Html.DisplayFor(modelItem => item.ReviewerDateEntered) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.ReviewerKey }) | @Html.ActionLink("Details", "Details", new { id=item.ReviewerKey }) | @Html.ActionLink("Delete", "Delete", new { id=item.ReviewerKey }) </td> </tr> } </table>
Modifying the Create
The Create new method is a little more complex. Rather than just add the reviewer to the collection of reviewers, we need to use the usp_NewReviewer stored procedure to add the new reviewer. This stored procedure is what adds the random integer seed and hashes the password.
Adjusting the form is not difficult. Just as we deleted the unwanted fields in the Index form, we can delete the divs for ReviewerSeedKey, ReviewerHashedPassword and ReviewerEntryDate. Here is the modified code and the form.
@model BookReviewMVCApp.Models.Reviewer @{ ViewBag.Title = "Create"; } <h2>Create</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Reviewer</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.ReviewerUserName, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.ReviewerUserName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ReviewerUserName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ReviewerFirstName, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.ReviewerFirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ReviewerFirstName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ReviewerLastName, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.ReviewerLastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ReviewerLastName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ReviewerEmail, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.ReviewerEmail, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ReviewerEmail, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ReviewPlainPassword, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.ReviewPlainPassword, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ReviewPlainPassword, "", 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> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
Next we will modify the controller. We will model the overloaded Create, the one with the Bind command in it. Just as in the view, we will remove the fields we don't want. In the if(model.IsValid) bloc we will replace the commands :
db.Reviewers.Add(reviewer); db.SaveChanges();
with this command:
db.usp_NewReviewer(reviewer.ReviewerUserName, reviewer.ReviewerFirstName, reviewer.ReviewerLastName, reviewer.ReviewerEmail, reviewer.ReviewPlainPassword);
Here is the complete method.
public ActionResult Create([Bind(Include = "ReviewerUserName,ReviewerFirstName,ReviewerLastName,ReviewerEmail, ReviewPlainPassword")] Reviewer reviewer) { if (ModelState.IsValid) { db.usp_NewReviewer(reviewer.ReviewerUserName, reviewer.ReviewerFirstName, reviewer.ReviewerLastName, reviewer.ReviewerEmail, reviewer.ReviewPlainPassword); return RedirectToAction("Index"); } return View(reviewer); }
Here are pictures of the form with the Create New and a new Reviewer, and the index after.
If we check the record in SQL Server, we can see that the hashed password and random seed are also provided. I should note, by the way, that the plain password is stored only for the convenience of the tutorial. NEVER STORE THE PASSWORD AS PLAIN TEXT IN REAL LIFE.
Modifying the Details and Delete Views
Next we will look at the Details veiw. It is very simple. As in the Index, we simply remove those fields we don't wish to see. Here is the result:
Modifying the Delete is exactly the same process. Just remove the fields we don't want users to see.
Modifying the Edit
The Edit is not quite so easy. First we remove the unwanted feilds from the view, specifically the Plain password, the key code and the hashed password. (Just delete the whole div with these elements.)
Next we need to modify the Edit code in the Controller. We can't just mark the record state as modified and let it make changes. For whatever reason, that puts nulls into whatever fields are not explicitly given a value in the edit. Here is the adjusted code.
public ActionResult Edit([Bind(Include = "ReviewerKey,ReviewerUserName,ReviewerFirstName,ReviewerLastName,ReviewerEmail,ReviewerKeyCode,ReviewerDateEntered")] Reviewer reviewer) { if (ModelState.IsValid) { //db.Entry(reviewer).State = EntityState.Modified; Reviewer rev = db.Reviewers.Find(reviewer.ReviewerKey); rev.ReviewerUserName = reviewer.ReviewerUserName; rev.ReviewerFirstName = reviewer.ReviewerFirstName; rev.ReviewerLastName = reviewer.ReviewerLastName; rev.ReviewerEmail = reviewer.ReviewerEmail; rev.ReviewerDateEntered = reviewer.ReviewerDateEntered; db.SaveChanges(); return RedirectToAction("Index"); } return View(reviewer); }
Now the edit works as advertised. Try changing Jeff's first name to Jeffery and check the results.
Modifying the Shared Layout Template
There are a couple of things we want to do here. One is put a link to our Reviewers index on the main page. The second is to modify the text on the main page to actually reflect our application.
To do the first, we edit the Nav bar div in the _Layout.cshtml. We add a an <li> tag with an @Html.ActionLink in it. The ActionLink takes three arguments: the text of the link on the form, the name of the view, and the name of the controller, minus the word "controller." Here is the code for the nav div:
<div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("About", "About", "Home")</li> <li>@Html.ActionLink("Contact", "Contact", "Home")</li> <li>@Html.ActionLink("Reviewers","Index","Reviewers")</li> </ul>
Now we have a menu link to our index page on the main form which works.
.The other thing we can do is change "Application Name" to "Book Reviews," by changing the code for the Html.ActionLink just below the button, just above the nav div.
@Html.ActionLink("Book Reviews", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
The next task is to change some of the Text on the main page. To do that we have to edit the Index view in the Home folder under views. Here is the page before any edits:
@{ ViewBag.Title = "Home Page"; } <div class="jumbotron"> <h1>ASP.NET</h1> <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p> <p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn more »</a></p> </div> <div class="row"> <div class="col-md-4"> <h2>Getting started</h2> <p> ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and gives you full control over markup for enjoyable, agile development. </p> <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more »</a></p> </div> <div class="col-md-4"> <h2>Get more libraries</h2> <p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p> <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301866">Learn more »</a></p> </div> <div class="col-md-4"> <h2>Web Hosting</h2> <p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p> <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301867">Learn more »</a></p> </div> </div>
Here is the modified Index under Home. I could do a lot more but I just want to show the gist.
@{ ViewBag.Title = "Home Page"; } <div class="jumbotron"> <h1>Book Review Club</h1> <p class="lead">The Best books, the best reviewers.</p> </div> <div class="row"> <div class="col-md-4"> <h2>Getting started</h2> <p> Register to add and review books. </p> </div> </div>
Here is a picture of the modified page.
The next tutorial will make a controller and views from scratch.
No comments:
Post a Comment