The details action method

Let us implement the details action method

Preparing the index view

First let us examine the last row of current code in index.cshtml file and understand how the details link work

<td>
 @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
 @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
 @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>

The scaffolding just created some boiler plate code previously, we will now replace it quit specific code as shown below, since we now have information about the model and its properties - in this case movie and Id:

Replacing last row of index.cshtml file

<td>
 <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
 <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
 <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>

Note:

  • we are using asp helper tags in place of razor expressions since it is easier to work with

  • the asp-action specifies which action method should be invoked on the controller

  • similarly, the asp-route-id appends the item Id as a route parameter as expected by our routing template

  • notice how we are using @ symbol do you use actual property - our primary key of movie model, Id in this case

In this manner, by using helper tags we are specifying which action method is to be called on the controller and also passing the corresponding object Id!

Preparing the controller

Let us first take a look at the existing code for the details action method of the movies controller

// GET: MoviesController/Details/5
public ActionResult Details(int id)
{
    return View();
}

Again, this is just a generic code we need to modify this in order to show the details of the selected movie in a Details form. Also note than this action method is invoked on an HTTP Get call, since we need to get the details from the server!

Modify the Details action as shown

// GET: MoviesController/Details/5
public ActionResult Details(int? id)
{          
    if (id == null || _context.Movie == null)
        return NotFound();

    var movie =  _context.Movie.Single(m => m.Id == id);

    if (movie == null)
        return NotFound();

    return View(movie);
}

Note:

  • NotFound() is a method inherited from the base controller - using these we don't have to remember status code for HTTP errors

  • Single() is a method which we can call on any collection using LINQ, to fetch a single object which matches the expression provided

  • if the movie is found we pass it to the view so that it can render the HTML based on the template we will create called the Detailsview shortly

Let us tidy the code

Add a constructor to the controller and instantiate _context inside it,

Also remove the fake context object creation from Index() method as well, since the constructor is doing it for us now

// constructor for the controller
public MoviesController() => 
           _context = new FakeContext();

Ad

Preparing the Details view

Using scaffolding again, let us add a razor view (inside Views\Movies folder) with the template as shown:

Click on Add

Here is the generated code for Details.cshtml file

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Id)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Id)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
    <a asp-action="Index">Back to List</a>
</div>

This is markup code based on the model we selected, it is creating a bunch of labels and text boxes in which we can display the details of the selected movie object.

Run the application now

Run the application now and access the movie list using the below URL

Hover the mouse on the Details hyperlink of second movie and you will see the URL that will be in invoked on clicking it, as prompted by the browser at its bottom section:

Click on Details link on any movie, and you will see the Details view!

This seems like a lot of code just to show the details of an item. There are ways where we can scaffold entire CRUD operations which includes views, controller and data access code but we just examined all the details by not doing so!

Last updated