Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Edit view in asp.net core mvc

Suggested Videos
Part 52 - Keeping domain models and database schema in sync in asp.net core | Text | Slides
Part 53 - File upload in asp.net core mvc | Text | Slides
Part 54 - Upload multiple files in asp.net core mvc | Text | Slides

In this video we will discuss implementing Edit view to edit existing data.


We want to display existing employee data on edit view as shown in the image below. The user can then change the details and click the Update button to update the data in the underlying database.


Edit view in asp.net core mvc

In this video we will discuss implementing edit view and in our next video we will discuss updating the data. When the Cancel button is clicked, redirect the user to the list view.

Navigating to Edit View

The following is our List View. 

asp.net core edit example

When the Edit button is clicked we want to redirect to the Edit view. In index.chtml modify the Edit anchor element as shown below.

<a asp-controller="home" asp-action="edit" asp-route-id="@employee.Id"
    class="btn btn-primary m-1">Edit</a>

Notice, we are using the following tag helpers to get to the Edit action in Home controller passing it the ID of the employee. 
  • asp-controller
  • asp-action
  • asp-route-*
The above code generates an URL that looks like the following. Edit is the action method in the HomeController and the value 1 is the ID of the employee being edited.

http://localhost/home/edit/1

Edit View Model

In the ViewModels folder include the following EmployeeEditViewModel class

public class EmployeeEditViewModel : EmployeeCreateViewModel
{
    public int Id { get; set; }
    public string ExistingPhotoPath { get; set; }
}

For your reference here is the EmployeeCreateViewModel class

public class EmployeeCreateViewModel
{
    [Required]
    [MaxLength(50, ErrorMessage = "Name cannot exceed 50 characters")]
    public string Name { get; set; }
    [Required]
    [RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
        ErrorMessage = "Invalid Email Format")]
    [Display(Name = "Office Email")]
    public string Email { get; set; }
    [Required]
    public Dept? Department { get; set; }
    public IFormFile Photo { get; set; }
}
  • This view model carries the data the Edit view needs
  • EmployeeEditViewModel class derives from EmployeeCreateViewModel
  • We used the inheritance approach in order not to duplicate code
  • In addition to the properties we inherited from EmployeeCreateViewModel class, we also need employee Id and ExistingPhotoPath properties in the EmployeeEditViewModel.
Edit Action Method in the Home Controller

Include the following Edit action method in the HomeController

[HttpGet]
public ViewResult Edit(int id)
{
    Employee employee = _employeeRepository.GetEmployee(id);
    EmployeeEditViewModel employeeEditViewModel = new EmployeeEditViewModel
    {
        Id = employee.Id,
        Name = employee.Name,
        Email = employee.Email,
        Department = employee.Department,
        ExistingPhotoPath = employee.PhotoPath
    };
    return View(employeeEditViewModel);
}
  • This Edit action method responds to the GET request.
  • It uses the injected Employee Repository instance to retrieve the employee details
  • Constructs the EmployeeEditViewModel instance and passes it to the Edit view
Edit View

The code is commented and self explanatory

@model EmployeeEditViewModel

@{
    ViewBag.Title = "Edit Employee";
    // Get the full path of the existing employee photo for display
    var photoPath = "~/images/" + (Model.ExistingPhotoPath ?? "noimage.jpg");
}

<form asp-controller="home" asp-action="edit" enctype="multipart/form-data" method="post" class="mt-3">
    <div asp-validation-summary="All" class="text-danger">
    </div>
    @*Use hidden input elements to store employee id and ExistingPhotoPath
        which we need when we submit the form and update data in the database*@
    <input hidden asp-for="Id" />
    <input hidden asp-for="ExistingPhotoPath" />

    @*Bind to the properties of the EmployeeEditViewModel. The asp-for tag helper
        takes care of displaying the existing data in the respective input elements*@
    <div class="form-group row">
        <label asp-for="Name" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Name" class="form-control" placeholder="Name">
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group row">
        <label asp-for="Email" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Email" class="form-control" placeholder="Email">
            <span asp-validation-for="Email" class="text-danger"></span>
        </div>
    </div>

    <div class="form-group row">
        <label asp-for="Department" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <select asp-for="Department" class="custom-select mr-sm-2"
                    asp-items="Html.GetEnumSelectList<Dept>()">
                <option value="">Please Select</option>
            </select>
            <span asp-validation-for="Department" class="text-danger"></span>
        </div>
    </div>

    <div class="form-group row">
        <label asp-for="Photo" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <div class="custom-file">
                <input asp-for="Photo" class="custom-file-input form-control">
                <label class="custom-file-label">Click here to change photo</label>
            </div>
        </div>
    </div>

    @*Display the existing employee photo*@
    <div class="form-group row col-sm-4 offset-4">
        <img class="imageThumbnail" src="@photoPath" asp-append-version="true" />
    </div>

    <div class="form-group row">
        <div class="col-sm-10">
            <button type="submit" class="btn btn-primary">Update</button>
            <a asp-action="index" asp-controller="home" class="btn btn-primary">Cancel</a>
        </div>
    </div>

    @section Scripts {
        <script>
            $(document).ready(function () {
                $('.custom-file-input').on("change", function () {
                    var fileName = $(this).val().split("\\").pop();
                    $(this).next('.custom-file-label').html(fileName);
                });
            });
        </script>
    }
</form>

Next Video : Implement Edit action that responds to HTTP Post and process the posted edit form.

asp.net core tutorial for beginners

6 comments:

  1. Hello, Thank you for great tutorial. I learn ASP.NET from your lessons. Can you please help with global exceptions? global exceptions doesnt work :/ I did everything according your tutorial. But app crashes with error unhandled exception.
    When I add anywhere to controllers or models throw new exception(); it crashes, it doesnt matter if env is development(dont show development exceptions page) or production(dont show error page). Even I try add throw new exception in any other app stil I get same error: unhanded exception.
    I use VS CE.
    If you have any idea, how I could solve, please let me know. I starting to be really despared :/
    Thank you in advance. D.

    ReplyDelete
  2. Hi Venkat,

    Thanks for this nice and extremely helpful video series on .net core. I am very much new here and trying to mimic what you are showing in these videos. However, I am having trouble when clicking on "Update" button. My new photo gets changed, but, I still get an

    NullReferenceException: Object reference not set to an instance of an object.

    for
    var existingphoto = "~/images/"+ (Model.existingPhotoPath ?? "user.png");

    Please guide me to the right direction to resolve this issue.

    Thanks in advance,

    Arindam

    ReplyDelete
    Replies
    1. Hi Venkat,

      Never mind. I found the answer. It was a mistake from my side. I forgot to return to "RedirectToAction" after the update. It is fixed now.

      Thanks,
      Arindam

      Delete

  3. **Suggestion :

    In httpGet Edit action method while assigning

    ExistingPhotoPath = employee.PhotoPath

    we should check for null in employee.PhotoPath if it's null then it should default file name should be assigned to it.

    eg:
    ExistingPhotoPath = employee.PhotoPath ?? "default.jpg";

    or else we will not see the image on the edit form as this ExistingPhotoPath property will be null and going forward if you update this image with the other image in the httppost Edit method it it will give the null argument exception at the time of deleting the old file from server in webroot folder.

    ReplyDelete
  4. I have been following the tutorial so far, but I am getting the following "NullReferenceException" error when I tested the Edit button. VS2019 highlights the "employeeEditViewModel" in the home controller. I noticed that the tutorial 55 in "EmployeeCreateViewModel" has "public IFormFile Photo { get; set; }" while in tutorial 54 shows "EmployeeCreateViewModel" having "public List Photo { get; set; }" Is there something that needs to be declared for the reference to be not null ??? I could not locate what I missing when I back track in the previous tutorials.... Any help would be appreciated.

    System.NullReferenceException: 'Object reference not set to an instance of an object.'

    EmployeeEditViewModel employeeEditViewModel = new EmployeeEditViewModel
    {
    Id = employee.Id,
    Name = employee.Name,
    Email = employee.Email,
    Department = employee.Department,
    ExistingPhotoPath = employee.PhotoPath
    };

    ReplyDelete
    Replies
    1. I fixed it. I copied the asp-action from index.cshtml, but forgot to change the asp-route-id to show "@Model.Employee.Id" instead of "@employee.id".

      Delete

It would be great if you can help share these free resources