Listing 2-1. The default contents of the HomeController class
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace PartyInvites.Controllers{ public class HomeController : Controller { public ActionResult Index() { return View(); } }}
Listing 2-2. Modifying the HomeController Class
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace PartyInvites.Controllers{ public class HomeController : Controller { public string Index() { return "Hello World"; } }}
Listing 2-3. Modifying the Controller to Render a View
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace PartyInvites.Controllers{ public class HomeController : Controller { public ViewResult Index() { return View(); } }}
Listing 2-4. Adding to the View HTML
@{ Layout = null;}Index Hello World (from the view)
Listing 2-5. Setting Some View Data
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace PartyInvites.Controllers{ public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon"; return View(); } }}
Listing 2-6. Retrieving a ViewBag Data Value
@{ Layout = null;}Index @ViewBag.Greeting World (from the view)
Listing 2-7. Displaying Details of the Party
@{ Layout = null;}Index @ViewBag.Greeting World (from the view)We're going to have an exciting party.
(To do: sell it better. Add pictures or something.)
Listing 2-8. The GuestResponse Domain Class
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace PartyInvites.Models{ public class GuestResponse { public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } public bool? WillAttend { get; set; } }}
Listing 2-9. Adding a Link to the RSVP Form
@{ Layout = null;}Index @ViewBag.Greeting World (from the view)We're going to have an exciting party.
(To do: sell it better. Add pictures or something.) @Html.ActionLink("RSVP Now", "RsvpForm")
Listing 2-10. Adding a New Action Method to the Controller
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace PartyInvites.Controllers{ public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon"; return View(); } public ViewResult RsvpForm() { return View(); } }}
Listing 2-12. The initial contents of the RsvpForm.cshtml file
@model PartyInvites.Models.GuestResponse@{ Layout = null;}RsvpForm
Listing 2-13. Creating a Form View
@model PartyInvites.Models.GuestResponse@{ Layout = null;}RsvpForm @using (Html.BeginForm()) {Your name: @Html.TextBoxFor(x => x.Name)
Your name: @Html.TextBoxFor(x => x.Email)
Your name: @Html.TextBoxFor(x => x.Phone)
Will you attend? @Html.DropDownListFor(x => x.WillAttend, new[]{ new SelectListItem(){Text = "Yes, I'll be there", Value = bool.TrueString}, new SelectListItem(){Text = "No, I can't come", Value = bool.FalseString} }, "Choose an option")
}
Listing 2-14. Adding an Action Method to Support POST Requests
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using PartyInvites.Models;namespace PartyInvites.Controllers{ public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon"; return View(); } [HttpGet] public ViewResult RsvpForm() { return View(); } [HttpPost] public ViewResult RsvpForm(GuestResponse guestResponse) { // TODO: Email response to the party organizer return View("Thanks", guestResponse); } }}
Listing 2-15. The Thanks View
@model PartyInvites.Models.GuestResponse@{ Layout = null;}Thanks Thanks you, @Model.Name!
@if (Model.WillAttend == true) { @:It's great that you're coming. The drinks area already in the fridge! } else { @:Sorry to hear that you can't make it, but thanks for letting us know. }
Listing 2-16. Applying Validation to the GuestResponse Model Class
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.ComponentModel.DataAnnotations;namespace PartyInvites.Models{ public class GuestResponse { [Required(ErrorMessage = "Please enter your name")] public string Name { get; set; } [Required(ErrorMessage = "Please enter your email address")] [RegularExpression(".+\\@.+\\..+", ErrorMessage = "Please enter a valid email address")] public string Email { get; set; } [Required(ErrorMessage = "Please enter your phone number")] public string Phone { get; set; } [Required(ErrorMessage = "Please specify whether you'll attend")] public bool? WillAttend { get; set; } }}
Listing 2-17. Checking for Form Validation Errors
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using PartyInvites.Models;namespace PartyInvites.Controllers{ public class HomeController : Controller { public ViewResult Index() { int hour = DateTime.Now.Hour; ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon"; return View(); } [HttpGet] public ViewResult RsvpForm() { return View(); } [HttpPost] public ViewResult RsvpForm(GuestResponse guestResponse) { if (ModelState.IsValid) { // TODO: Email response to the party organizer return View("Thanks", guestResponse); } else { // there is validation error return View(); } } }}
Listing 2-18. Using the Html.ValidationSummary Help Method
@model PartyInvites.Models.GuestResponse@{ Layout = null;}RsvpForm @using (Html.BeginForm()) { @Html.ValidationSummary()Your name: @Html.TextBoxFor(x => x.Name)
Your email: @Html.TextBoxFor(x => x.Email)
Your phone: @Html.TextBoxFor(x => x.Phone)
Will you attend? @Html.DropDownListFor(x => x.WillAttend, new[]{ new SelectListItem(){Text = "Yes, I'll be there", Value = bool.TrueString}, new SelectListItem(){Text = "No, I can't come", Value = bool.FalseString} }, "Choose an option")
}
Listing 2-19. The contents of the Content/Site.css file
.field-validation-error { color: #f00;}.field-validation-valid { display: none;}.input-validation-error { border: 1px solid #f00; background-color: #fee; }.validation-summary-errors { font-weight: bold; color: #f00;}.validation-summary-valid { display: none;}
Listing 2-20. Adding the link element to the RsvpForm view
@model PartyInvites.Models.GuestResponse@{ Layout = null;}RsvpForm @using (Html.BeginForm()) { @Html.ValidationSummary()Your name: @Html.TextBoxFor(x => x.Name)
Your email: @Html.TextBoxFor(x => x.Email)
Your phone: @Html.TextBoxFor(x => x.Phone)
Will you attend? @Html.DropDownListFor(x => x.WillAttend, new[]{ new SelectListItem(){Text = "Yes, I'll be there", Value = bool.TrueString}, new SelectListItem(){Text = "No, I can't come", Value = bool.FalseString} }, "Choose an option")
}
Listing 2-21. Using the WebMail Helper
@model PartyInvites.Models.GuestResponse@{ Layout = null;}Thanks @{ try { WebMail.SmtpServer = "smtp.example.com"; WebMail.SmtpPort = 587; WebMail.EnableSsl = true; WebMail.UserName = "mySmtpUsername"; WebMail.Password = "mySmtpPassword"; WebMail.From = "rsvps@example.com"; WebMail.Send("party-host@example.com", "RSVP Notification", Model.Name + " is " + ((Model.WillAttend ?? false) ? " " : "not ") + "attending"); } catch(Exception) { @:Sorry - we coundn't send the email to confirm your RSVP. } }Thanks you, @Model.Name!
@if (Model.WillAttend == true) { @:It's great that you're coming. The drinks area already in the fridge! } else { @:Sorry to hear that you can't make it, but thanks for letting us know. }