Koalemos
Koalemos

Reputation: 41

ASP.NET MVC - Lists

I am making a project about movies. I want the movietitles to be displayed in a list on the startpage, when you click on one of the listitems it should redirect to a subpage (Movie.cshtml) with the movietitle in the url. The information on that page should be title, genre, year and country for that specific movie.

My StartController.cs:

using IMDB.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace IMDB.Controllers
{
    public class StartController : Controller
    {
        // GET: Start
        public ActionResult Index()
        {
            var movieList = new List<Movies>();
            movieList.Add(new Movies() { Title = "Terminator", Genre = "Action", Year = 1984, Country = "America" });
            movieList.Add(new Movies() { Title = "Terminator II", Genre = "Action", Year = 1984, Country = "America" });

            return View(movieList);
        }

        public ActionResult Movie(string title)
        {
            return View();
        }
    }
}

I have already configured RouteConfig.cs to include Title in the url:

routes.MapRoute(
    name: "Default",
    url: "{action}/{title}",
    defaults: new { controller = "Start", action = "Index", title = "Title"
});

And the list of movies in my Index.cshtml:

@model List<IMDB.Models.Movies>
@{
    ViewBag.Title = "Start";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Welcome to My Movie Database</h2>

<ul>
    @foreach (var movie in Model)
    {
        <li>
            @Html.ActionLink(movie.Title, "Movie", new { title = movie.Title})
        </li>
    }
</ul>

And this is my Movie.cshtml page:

@model IMDB.Models.Movies

@{
    ViewBag.Title = "Movie";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
    <h2>@Html.DisplayFor(model => model.Title)</h2>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Title)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Title)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Genre)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Genre)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Year)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Year)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Country)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Country)
        </dd>

    </dl>
</div>

So my question is, how do I get that unique information from my list?

Upvotes: 1

Views: 1314

Answers (3)

Top Rat
Top Rat

Reputation: 415

You can make another method in the controller with the modified route and parameters.

You should probably also store the movies somewhere, a repository perhaps?, instead of a list in another scope.

[HttpGet("movies/{title}")]
public ActionResult Movie(string title)
{
    // Recreate list here... or store it somewhere and query against it in the below line
    Movie movie = movieList.FirstOrDefault(x => x.Title == title);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

Upvotes: 0

Win
Win

Reputation: 62260

First of all, Class name should be always Singular - Movie.

public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Genre { get; set; }
    public int Year { get; set; }
    public string Country { get; set; }
}

Second, you want to use Identifier when passing value in query string.

Title can be contain special character such as : &. If so, it won't be valid URL, and you won't be able to retrieve movie from title.

public class StartController : Controller
{
    // This could later comes from Database. 
    public IList<Movie> Movies
    {
        get
        {
            var movies = new List<Movie>
            {
                new Movie {Id = 1, Title = "Terminator", Genre = "Action", Year = 1984, Country = "America"},
                new Movie {Id = 2, Title = "Terminator II", Genre = "Action", Year = 1984, Country = "America"}
            };
            return movies;
        }
    }

    // GET: Start
    public ActionResult Index()
    {
        return View(Movies);
    }

    public ActionResult Movie(int id)
    {
        var movie = Movies.FirstOrDefault(m => m.Id == id);
        return View(movie);
    }
}

View

<ul>
    @foreach (var movie in Model)
    {
        <li>
            @Html.ActionLink(movie.Title, "Movie", new { id = movie.Id})
        </li>
    }
</ul>

Upvotes: 0

Gasper
Gasper

Reputation: 3030

Keep in mind, that the list you created in Index method will cease to exist after the page will be rendered. Client-side page have no connection to your code that is run on the server.

You will need to retrieve Movie data using only its name in your Movie method. E.g., if you're using a stub list instead of DB query, you will need to make it visible inside that method too:

public class StartController : Controller
{
    List<Movie> movieList = new List<Movies>()
    {
        new Movies() { Title = "Terminator", Genre = "Action", Year = 1984, Country = "America" },
        new Movies() { Title = "Terminator II", Genre = "Action", Year = 1984, Country = "America" }
    };

    // GET: Start
    public ActionResult Index()
    {
        return View(movieList);
    }

    public ActionResult Movie(string title)
    {
        var movie = movieList.Where(x => x.Title == title).FirstOrDefault();
        return View(movie);
    }
}

In this scenario you can, of course, just use list of titles in Index method instead of the whole object.

Upvotes: 2

Related Questions