Variable in Index Method Re: View Model

Dean Everhart 1,541 Reputation points
2023-01-14T15:41:18.7533333+00:00

Where does movieGenre in the code below come from? I do not see movieGenre in the model or view model. Is it a variable first created within the index action method? Could it be anything..."apple" for instance, as long as it is the same in the code below?

Based on Tutorial: https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/search?view=aspnetcore-6.0

public async Task<IActionResult> Index(string movieGenre, string searchString)

Apple Example:

// GET: Movies
public async Task<IActionResult> Index(string 
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;
    var movies = from m in _context.Movie
                 select m;

    if (!string.IsNullOrEmpty(searchString))
    {
        movies = movies.Where(s => s.Title!.Contains(searchString));
    }

    if (!string.IsNullOrEmpty(
    {
        movies = movies.Where(x => x.Genre == 
    }

    var movieGenreVM = new MovieGenreViewModel
    {
        Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
        Movies = await movies.ToListAsync()
    };

    return View(movieGenreVM);
}

Based on Tutorial: [https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/search?view=aspnetcore-6.0

Full Code Below:

using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
}
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace MvcMovie.Models
{
    public class MovieGenreViewModel
    {
        public List<Movie>? Movies { get; set; }
        public SelectList? Genres { get; set; }
        public string? MovieGenre { get; set; }
        public string? SearchString { get; set; }
    }
}
// GET: Movies
public async Task<IActionResult> Index(string movieGenre, string searchString)
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;
    var movies = from m in _context.Movie
                 select m;

    if (!string.IsNullOrEmpty(searchString))
    {
        movies = movies.Where(s => s.Title!.Contains(searchString));
    }

    if (!string.IsNullOrEmpty(movieGenre))
    {
        movies = movies.Where(x => x.Genre == movieGenre);
    }

    var movieGenreVM = new MovieGenreViewModel
    {
        Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
        Movies = await movies.ToListAsync()
    };

    return View(movieGenreVM);
}
@model MvcMovie.Models.MovieGenreViewModel

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

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<form asp-controller="Movies" asp-action="Index" method="get">
    <p>

        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>

        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Movies)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ReleaseDate)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Genre)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Price)
                </td>
                <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>
            </tr>
        }
    </tbody>
</table>
Developer technologies ASP.NET ASP.NET Core
Developer technologies ASP.NET Other
0 comments No comments
{count} votes

Accepted answer
  1. AgaveJoe 30,126 Reputation points
    2023-01-14T16:24:40.4033333+00:00

    Where does movieGenre in the code below come from? I do not see movieGenre in the model or view model.

    The movieGenre parameter is within an HttpGet action. The data is within the URL and invoked usually when a user clicks a a link but it can be a form if the form method is a GET rather than a post. A model or view model is submitted in a form post (message body), clicking a button.

    In this example the form is submitted as a GET which means the data is in the URL. ie. localhost/conrtroller/index/?MovieGenre=data1&SearchString=data2

    This is explained rather openly in the links you provided. If you are still unclear then study the difference between an HTTP POST and HTTP GET. Understanding GET and POST is a very important concept in MVC becase it is one of the way an action is selected.

    HTTP Request Methods

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Dean Everhart 1,541 Reputation points
    2023-01-15T17:32:52.45+00:00

    So...am I correct that there is an error / typo in the Tutorial: MovieGenre in View Model, movieGenre in the action method and MovieGenre in the View.

    The "m" in movieGenre in the Action Method should not be lowercase.

    ViewModel

    public string? MovieGenre { get; set; }
    

    Action Method

    public async Task<IActionResult> Index(string movieGenre, string searchString)
    

    View

            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.