Exercises: Edit Model Classes

Add functionality to edit event objects in your CodingEvents application. These exercises assume that you have added all of the code from this section of the book and your application resembles the models branch .

The edit form will resemble the form used to create an event.

Tip

As you work through these steps, test your code along the way! With each change you apply to your code, ask yourself what you expect to see when the application is run. You may not find that all of the steps result in observable changes, though. Use Visual Studio’s debugging tools and read your error messages if you run into issues after applying any of the changes.

  1. Create the two action methods listed below in EventsController. We’ll add code to these in a moment, so just put the outline in place for now.

    1. Create an action method to display an edit form with this signature:

      1
      2
      3
      
         public IActionResult Edit(int eventId) {
            // controller code will go here
         }
    2. Create an action method to process the form with this signature:

      1
      2
      3
      4
      
         [HttpPost]
         public IActionResult SubmitEditEventForm(int eventId, string name, string description) {
            // controller code will go here
         }
  2. Add the necessary annotations to the SubmitEditEventForm() method for it to live at the path /Events/Edit.

    1
    2
    3
    4
    5
    6
    
    [HttpPost]
    [Route("Events/Edit")]
    public IActionResult SubmitEditEventForm(int eventId, string name, string description)
    {
       // controller code will go here
    }
  3. You’ll need to configure the route for Edit() to include the path variable eventId, so that paths like /Events/Edit/3 will work.

    1
    2
    3
    4
    5
    6
    
    [HttpPost]
    [Route("Events/Edit/{eventId}")]
    public IActionResult Edit(int eventId)
    {
       // controller code will go here
    }
  4. Create an Edit.cshtml view in Views/Events.

  5. Copy the code from Add.cshtml into Edit.cshtml.

    1. You’ll want to update the text of the submit button and the heading to reflect the edit functionality.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    <h1>Edit Event</h1>
    
    <form method="post">
       <div class="form-group">
          <label for="name">Name</label>
          <input name="name" type="text" />
       </div>
       <div class="form-group">
          <label for="description">Description</label>
          <input name="description" />
       </div>
       <input type="submit" value="Edit Event" />
    </form>
  6. Back in EventsController, round out the Edit() method.

    1. Use an EventData method to find the event object with the given eventId.

    2. Put the event object in ViewBag.

    3. Return the appropriate view.

    1
    2
    3
    4
    5
    6
    7
    8
    
    [HttpGet]
    [Route("Events/Edit/{eventId}")]
    public IActionResult Edit(int eventId)
    {
       Event editingEvent = EventData.GetById(eventId);
       ViewBag.eventToEdit = editingEvent;
       return View();
    }
  7. Within the form fields in Edit.cshtml,

    1. Get the name and description from the event that was passed in via ViewBag and set them as the values of the form fields.

    2. Add action="/events/edit" to the form tag.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    <h1>@ViewBag.title</h1>
    
    <form method="post" action="/events/edit">
       <div class="form-group">
          <label for="name">Name</label>
          <input name="name" type="text" value="@ViewBag.eventToEdit.Name"/>
       </div>
       <div class="form-group">
          <label for="description">Description</label>
          <input name="description" type="text" value="@ViewBag.eventToEdit.Description" />
       </div>
       <input type="submit" value="Edit Event" />
    
    </form>
  8. Add another input to hold the id of the event being edited. This should be hidden from the user:

       <input type="hidden" value="@ViewBag.eventToEdit.Id" name="eventId" />
    Note

    You may not have named your ViewBag property eventToEdit. Make sure you are using the name you gave your property!

    1
    2
    3
    4
    5
    
    <!-- description div code here -->
       </div>
       <input type="hidden" value="@ViewBag.eventToEdit.Id" name="eventId">
       <input type="submit" value="Edit Event" />
    </form>
  9. Back in the Edit() action method, add a title to ViewBag that reads “Edit Event NAME (id=ID)" where "NAME" and "ID" are replaced by the values for the given event.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    [HttpGet]
    [Route("Events/Edit/{eventId}")]
    public IActionResult Edit(int eventId)
    {
       Event editingEvent = EventData.GetById(eventId);
       ViewBag.eventToEdit = editingEvent;
       ViewBag.title = "Edit Event " + editingEvent.Name + "(id = " + editingEvent.Id + ")";
       return View();
    }
  10. In SubmitEditEventForm(),

    1. Query EventData for the event being edited with the given id parameter.

    2. Update the name and description of the event.

    3. Redirect the user to /Events (the event listing page).

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    [HttpPost]
    [Route("Events/Edit")]
    public IActionResult SubmitEditEventForm(int eventId, string name, string description)
    {
       Event editingEvent = EventData.GetById(eventId);
       editingEvent.Name = name;
       editingEvent.Description = description;
       return Redirect("/Events");
    }
  11. To access event editing, the user will need an edit option in the list of event data.

    1. In Index.cshtml, add a link to edit the event as a column in the event table:

         <td><a asp-controller="Events" asp-action="Edit" asp-route-id="@evt.Id">Edit Event</a></td>

      asp-route-id is a new tag helper for us. Our routes normally go /<controller>/<action>. asp-route-id passes an {id?} parameter at the end of our route. When the site is built, we can inspect it and see that for the first item in the table this line of HTML will look like:

         <td><a href="/Events/Edit/1">Edit Event</a></td>
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
     @foreach (var evt in ViewBag.events)
       {
          <tr>
             <td>@evt.Id</td>
             <td>@evt.Name</td>
             <td>@evt.Description</td>
             <td><a asp-controller="Events" asp-action="Edit" asp-route-id="@evt.Id">Edit Event</a></td>
          </tr>
       }
    </table>