Reputation: 41
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
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
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);
}
}
<ul>
@foreach (var movie in Model)
{
<li>
@Html.ActionLink(movie.Title, "Movie", new { id = movie.Id})
</li>
}
</ul>
Upvotes: 0
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