ASP.NET MVC - 路由适用于 /home 但不适用于 /home/index

ASP.NET MVC - Routing works for /home but not for /home/index

我正在尝试为在线完成的项目添加视图。

当我加载默认网页时,Home 控制器中的索引操作会加载。当我导航到 /home 时,Home 控制器中的 Index 操作会加载。但是,当我导航到 /home/index 时,会弹出一个错误。

这是我启动时的默认路由 class:

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" });
            })

这是我在家庭控制器中的索引方法:

public class HomeController : Controller
    {
        private readonly IMovieRankService _movieRankService;

        public HomeController(IMovieRankService movieRankService)
        {
            _movieRankService = movieRankService;
        }

        [HttpGet]
        public async Task<ActionResult> Index()
        {
            var other = await _movieRankService.GetAllItemsFromDatabase();
            return View(other);
        }

我的索引视图:

@using Movie_Rank.Contracts;
@model IEnumerable<MovieResponse>

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

<h2>movies</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.MovieName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Description)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Ranking)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.TimeRanked)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.MovieName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Ranking)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TimeRanked)
            </td>
            <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>
        </tr>
}
    </tbody>
</table>

当我 运行 程序时,我的 table 电影可以正常加载。 当我将 /home 放入 url 时,我的 table 电影加载正常。 但是当我输入 /home/index 时,它给出了这个错误:

    NullReferenceException: Object reference not set to an instance of an object.
MovieRank.Libs.Mappers.Mapper.ToMovieContract(MovieDb movie) in Mapper.cs
-
        18. }
        19.
        20. public MovieResponse ToMovieContract(MovieDb movie)
        21. {
        22.     // Returns new MovieResponse which maps proprties of MovieDb (using DynamoDB table attributes
        23.     // For example, MovieName (from MovieResponse class) = movie.MovieName (from MovieDb)
      **24.**   return new MovieResponse
        25.     {
        26.         MovieName = movie.MovieName,
        27.         Description = movie.Description,
        28.         Actors = movie.Actors,
        29.         Ranking = movie.Ranking,
        30.         TimeRanked = movie.RankedDateTime
MovieRank.Services.MovieRankService.GetMovie(int userId, string movieName) in MovieRankService.cs
-
        31. 
        32. // Get a movie from MovieDb in MovieRankRepository and map to MovieResponse
        33. public async Task<MovieResponse> GetMovie(int userId, string movieName)
        34. {
        35.     var response = await _movieRankRepository.GetMovie(userId, movieName);
        36.     // Uses MovieRankRepository response
      **37.**   return _map.ToMovieContract(response);
        38. }
        39.
        40. // Get movies from MovieDb in MovieRankRepository and map to MovieResponse
        41. public async Task<IEnumerable<MovieResponse>> GetUsersRankedMoviesByMovieTitle(int userId, string movieName)
        42. {
        43.     var response = await _movieRankRepository.GetUsersRankedMoviesByMovieTitle(userId, movieName);
MovieRank.Controllers.HomeController.GetMovie(int userId, string movieName) in HomeController.cs
-
        25. }
        26. 
        27. [HttpGet]
        28. [Route("{userId}/{movieName}")]
        29. public async Task<ActionResult> GetMovie(int userId, string movieName)
        30. {
      **31.**   var result = await _movieRankService.GetMovie(userId, movieName);
        32. 
        33.     return View(result);
        34. }
        35. 
        36. [HttpGet]
        37. [Route("user/{userId}/rankedMovies/{movieName}")]

所以我们知道当您使用 /Home/Index 时,它正在使用此操作:

public async Task<ActionResult> GetMovie(int userId, string movieName)

这与你给它的路线有关:

[Route("{userId}/{movieName}")]

因为此时路由不知道 userId 应该是什么类型,所以它匹配 userId = "Home"movieName = "Index"。然后当映射值时,值类型不匹配,我假设您可能在方法本身中为 userId 获得 0

尝试在路线中添加 constraint,以确保仅当 userIdint 时才会选择路线:

[Route("{userId:int}/{movieName}")]