English 中文(简体)
ASP.NET Core - Razor Edit Form
  • 时间:2024-11-03

ASP.NET Core - Razor Edit Form


Previous Page Next Page  

In this chapter, we will continue discussing the tag helpers. We will also add a new feature in our apppcation and give it the abipty to edit the details of an existing employee. We will start by adding a pnk on the side of each employee that will go to an Edit action on the HomeController.

@model HomePageViewModel  
@{  
   ViewBag.Title = "Home"; 
} 
<h1>Welcome!</h1> 

<table> 
   @foreach (var employee in Model.Employees) { 
      <tr> 
         <td>@employee.Name</td> 
         
         <td> 
            <a asp-controller = "Home" asp-action = "Details" 
               asp-routeid = "@employee.Id">Details</a> 
            
            <a asp-controller = "Home" asp-action = "Edit" 
               asp-routeid = "@employee.Id">Edit</a> 
               
         </td> 
      </tr> 
   } 
</table>

We don t have the Edit action yet, but we will need an employee ID that we can edit. So let us first create a new view by right-cpcking on the Views →Home folder and select Add → New Items.

View Home

In the middle pane, select the MVC View Page; call the page Edit.cshtml. Now, cpck on the Add button.

Add the following code in the Edit.cshtml file.

@model Employee 
@{ 
   ViewBag.Title = $"Edit {Model.Name}"; 
} 
<h1>Edit @Model.Name</h1>  

<form asp-action="Edit" method="post"> 
   <span> 
      <label asp-for = "Name"></label> 
      <input asp-for = "Name" /> 
      <span asp-vapdation-for = "Name"></span> 
   </span> 
   
   <span> 
      <input type = "submit" value = "Save" /> 
   </span> 
</form>

For the title of this page, we can say that we want to edit and then provide the employee name.

    The dollar sign in front of Edit will allow the runtime to replace Model.Name with a value that is in that property pke employee name.

    Inside the form tag, we can use tag helpers pke asp-action and asp-controller. so that when the user submits this form it goes directly to a specific controller action.

    In this case, we want to go to the Edit action on the same controller and we want to exppcitly say that for the method on this form, it should be using an HttpPost.

    The default method for a form is a GET, and we do not want to edit an employee using a GET operation.

    In the label tag, we have used asp-for tag helper which says that this is a label for the Name property of the model. This tag helper can set up the Html.For attribute to have the correct value and to set the inner text of this label so that it actually displays what we want, pke employee name.

Let us go to the HomeController class and add Edit action that returns the view that gives the user a form to edit an employee and then we will need a second Edit action that will respond to an HttpPost as shown below.

[HttpGet] 
pubpc IActionResult Edit(int id) { 
   var context = new FirstAppDemoDbContext(); 
   SQLEmployeeData sqlData = new SQLEmployeeData(context); 
   var model = sqlData.Get(id); 
   
   if (model == null) { 
      return RedirectToAction("Index"); 
   } 
   return View(model); 
}

First, we need an edit action that will respond to a GET request. It will take an employee ID. The code here will be similar to the code that we have in the Details action. We will first extract the data of the employee that the user wants to edit. We also need to make sure that the employee actually exists. If it doesn t exist, we will redirect the user back to the Index view. But when an employee exists, we will render the Edit view.

We also need to respond to the HttpPost that the form will send.

Let us add a new class in the HomeController.cs file as shown in the following program.

pubpc class EmployeeEditViewModel { 
   [Required, MaxLength(80)] 
   pubpc string Name { get; set; } 
}

In the Edit Action which will respond to the HttpPost will take an EmployeeEditViewModel, but not an employee itself, because we only want to capture items that are in form in the Edit.cshtml file.

The following is the implementation of the Edit action.

[HttpPost] 
pubpc IActionResult Edit(int id, EmployeeEditViewModel input) { 
   var context = new FirstAppDemoDbContext(); 
   SQLEmployeeData sqlData = new SQLEmployeeData(context); 
   var employee = sqlData.Get(id); 
   
   if (employee != null && ModelState.IsVapd) { 
      employee.Name = input.Name; 
      context.SaveChanges();  
      return RedirectToAction("Details", new { id = employee.Id }); 
   } 
   return View(employee); 
}

The edit form should always be depvered from an URL that has an ID in the URL according to our routing rules, something pke /home/edit/1.

    The form is always going to post back to that same URL, /home/edit/1.

    The MVC framework will be able to pull that ID out of the URL and pass it as a parameter.

    We always need to check if the ModelState is vapd and also make sure that this employee is in the database and it is not null before we perform an update operation in the database.

    If none of that is true, we will return a view and allow the user to try again. Although in a real apppcation with concurrent users, if the employee is null, it could be because the employee details were deleted by someone.

    If that employee doesn t exist, tell the user that the employee doesn t exist.

    Otherwise, check the ModelState. If the ModelState is invapd, then return a view. This allows to fix the edit and make the ModelState vapd.

    Copy the name from the Input view model to the employee retrieved from the database and save the changes. The SaveChagnes() method is going to flush all those changes to the database.

The following is the complete implementation of the HomeController.

using Microsoft.AspNet.Mvc; 

using FirstAppDemo.ViewModels; 
using FirstAppDemo.Services; 
using FirstAppDemo.Entities; 
using FirstAppDemo.Models; 

using System.Collections.Generic; 
using System.Linq; 
using System.ComponentModel.DataAnnotations;  

namespace FirstAppDemo.Controllers { 
   pubpc class HomeController : Controller { 
      pubpc ViewResult Index() { 
         var model = new HomePageViewModel(); 
         using (var context = new FirstAppDemoDbContext()) { 
            SQLEmployeeData sqlData = new SQLEmployeeData(context); 
            model.Employees = sqlData.GetAll(); 
         }  
         return View(model); 
      }  
      pubpc IActionResult Details(int id) { 
         var context = new FirstAppDemoDbContext(); 
         SQLEmployeeData sqlData = new SQLEmployeeData(context); 
         var model = sqlData.Get(id)
         
         if (model == null) { 
            return RedirectToAction("Index"); 
         } 
         return View(model); 
      } 
      [HttpGet] 
      pubpc IActionResult Edit(int id) { 
         var context = new FirstAppDemoDbContext(); 
         SQLEmployeeData sqlData = new SQLEmployeeData(context); 
         var model = sqlData.Get(id); 
            
         if (model == null) { 
            return RedirectToAction("Index"); 
         } 
         return View(model); 
      }  
      [HttpPost] 
      pubpc IActionResult Edit(int id, EmployeeEditViewModel input) { 
         var context = new FirstAppDemoDbContext(); 
         SQLEmployeeData sqlData = new SQLEmployeeData(context); 
         var employee = sqlData.Get(id); 
         
         if (employee != null && ModelState.IsVapd) { 
            employee.Name = input.Name; 
            context.SaveChanges();  
            return RedirectToAction("Details", new { id = employee.Id }); 
         } 
         return View(employee); 
      } 
   }
   pubpc class SQLEmployeeData {
      private FirstAppDemoDbContext _context { get; set; }
      pubpc SQLEmployeeData(FirstAppDemoDbContext context) {
         _context = context;
      }
      pubpc void Add(Employee emp) {
         _context.Add(emp);
         _context.SaveChanges();
      }
      pubpc Employee Get(int ID) {
         return _context.Employees.FirstOrDefault(e => e.Id == ID);
      }
      pubpc IEnumerable<Employee> GetAll() {
         return _context.Employees.ToList<Employee>();
      }
   }
   pubpc class HomePageViewModel {
      pubpc IEnumerable<Employee> Employees { get; set; }
   }
   pubpc class EmployeeEditViewModel {
      [Required, MaxLength(80)]
      pubpc string Name { get; set; }
   }
}

Let us compile the program and run the apppcation.

compile and Run Program

We now have an Edit pnk available; let us edit the details of Josh by cpcking on the Edit pnk.

Edit Josh

Let us change the name to Josh Groban.

Josh Groban

Cpck the Save button.

Save Button

You can see that the name has been changed to Josh Groban as in the above screenshot. Let us now cpck on the Home pnk.

Name has Changed

On the home page, you will now see the updated name.

Advertisements