MVC 4 - маршруты превращаются в строку запроса

Я скачал пример базы данных Chinook и пытаюсь создать простое приложение для обучения MVC 4 и EF. Chinook - это группа артистов, их альбомов и треков в каждом альбоме. Я хотел создать REST-подобную структуру URL для отображения каждого исполнителя, его альбомов и треков. Это то, что я предполагал:

Chinook/Artist                              <- List of artists
Chinook/Artist/{id}                         <- Artist details
Chinook/Artist/{id}/Album                   <- List of albums for artist
Chinook/Artist/{id}/Album/{id}              <- Details for an album
Chinook/Artist/{id}/Album/{id}/Track        <- Track listing for album
Chinook/Artist/{id}/Album/{id}/Track/{id}   <- Track details

Вот как выглядит мой Route.config:

 routes.MapRoute(
    name: "chinook_artist",
    url: "Chinook/Artist/{id}/{action}",
    defaults: new { controller = "Artist", action = "Index", id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "chinook_album",
    url: "Chinook/Artist/{ArtistId}/Album/{id}/{action}",
    defaults: new { controller = "Album", action = "Index", id = UrlParameter.Optional, ArtistId = UrlParameter.Optional }
);

routes.MapRoute(
    name: "chinook_track",
    url: "Chinook/Artist/{ArtistId}/Album/{AlbumId}/Track/{id}/{action}",
    defaults: new { controller = "Track", action = "Index", id = UrlParameter.Optional, ArtistId = UrlParameter.Optional, AlbumId = UrlParameter.Optional }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Моя идея состояла в том, чтобы иметь Edit, Delete а также Add действия, а также для всех трех типов объектов, и Index будет служить в качестве листинга.

Это работает достаточно хорошо, однако вот как выглядят мои URL:

http://localhost:57264/Album/?ArtistId=8&AlbumId=10&TrackId=70

Во всех случаях я использую Html.ActionLink с контроллером, действием и т. д. Для генерации ссылок в представлениях. Но я не могу заставить свои URL начинаться с "Chinook" и быть "чистым", а не использовать строку запроса, например так:

http://localhost:57264/Chinook/Artist/8/Album/10/Track/70

Так что я не уверен, что я делаю не так здесь. Я иду против зерна того, как MVC должен работать? Мои маршруты определены неправильно?

1 ответ

Решение

Глядя на последние 2 маршрута

Chinook/Artist/{id}/Album/{id}/Track
Chinook/Artist/{id}/Album/{id}/Track/{id}

Ваши определения маршрута должны быть

//Chinook/Artist/{artistid}/Album/{albumid}/Track
routes.MapRoute(
  name: "chinook_track",
  url: "Chinook/Artist/{ArtistId}/Album/{AlbumId}/Track",
  defaults: new { controller = "Track", action = "Index" }
);

//Chinook/Artist/{artistid}/Album/{albumid}/Track/{id}
routes.MapRoute(
  name: "chinook_trackdetails",
  url: "Chinook/Artist/{ArtistId}/Album/{AlbumId}/Track/{id}",
  defaults: new { controller = "Track", action = "Details", id = UrlParameter.Optional }
);

и ваш контроллер

public class TrackController : Controller
{
  public ActionResult Index(int ArtistId, int AlbumId)
  {
    ....
  }
  public ActionResult Details(int ArtistId, int AlbumId, int id)
  {
    ....
  }
}

и в представлении, генерировать ссылки как

@Html.ActionLink("Index", "Index", "Track", new { ArtistId = 5, AlbumId  = 3 }, null)
@Html.ActionLink("Details", "Details", "Track", new { ArtistId = 5, AlbumId = 3, id = 7 }, null)

Затем, если вы хотите, чтобы маршрут редактировал дорожку в аналогичном формате

//Chinook/Artist/{artistid}/Album/{albumid}/Track/{id}/Edit
routes.MapRoute(
  name: "chinook_trackedit",
  url: "Chinook/Artist/{ArtistId}/Album/{AlbumId}/Track/{id}/Edit",
  defaults: new { controller = "Track", action = "Edit"}
);

public ActionResult Edit(int ArtistId, int AlbumId, int id)
{
  ....
}

@Html.ActionLink("Edit", "Edit", "Track", new { ArtistId = 5, AlbumId = 3, id = 7 }, null)
Другие вопросы по тегам