#asp.net-mvc #asp.net-mvc-3 #routes #global-asax
#asp.net-mvc #asp.net-mvc-3 #маршруты #глобальный-asax
Вопрос:
Я думаю, что я уже спрашивал об этом, но решение на самом деле не имело смысла. В любом случае, у меня есть ссылки на действия в моих представлениях, подобные этому:
foreach( var item in Model){
<%: Html.ActionLink(item.Name, "Details", new {id = item.Id}) %>
}
теперь, когда он переходит к деталям моего действия, очевидно, что это будет URL
/MyThings/Details/{id}
Мне было интересно, возможно ли отобразить имя этого элемента вместо идентификатора с помощью slug? или изменение глобального asax следующим образом:
/MyThings/Details/CarKeys
Дело в том, что имена должны быть уникальными, есть ли способ изменить глобальный asax, чтобы показывать имя вместо идентификатора?
Любые советы приветствуются!
Ответ №1:
Если это исключительно для целей SEO, просто укажите как идентификатор, так и имя. Имя будет частью URL-адреса, но не будет использоваться вашим приложением. Просто добавьте другой маршрут, который использует шаблон: {controller}/{action}/{id}/{name}
Вы также захотите преобразовать свое имя, чтобы убедиться, что оно содержит только допустимые символы для URL-адресов. В сети есть множество статей об этом, и это довольно просто. Вот пример: http://chrismckee.co.uk/creating-url-slugs-permalinks-in-csharp /
Комментарии:
1. ну, это больше для улучшения пользовательского интерфейса, возьмите rottentomatoes.com например, если я нажму на ссылку >> rottentomatoes.com/m/the_ides_of_march это направит меня к этой записи на контроллере M. я думал, что они, вероятно, использовали этот заголовок в качестве ключа в записи? нет? и спасибо за ссылку, кстати!
Ответ №2:
Конечно, вам просто нужно изменить правила маршрутизации. Найдите в своем файле Global.asax.cs или в файле регистрации вашей области что-то вроде этого:
routes.MapRoute(..., "{controller}/{action}/{id}", ...);
… и измените его на что-то вроде этого:
routes.MapRoute(..., "{controller}/{action}/{name}", ...);
Затем пусть ваше действие примет имя вместо идентификатора:
Html.ActionLink(item.Name, "Details", new {item.Name})
Комментарии:
1. да, но для этого потребуется изменить запросы, чтобы они правильно попадали на контроллер? итак, от общедоступных сведений о ActionResult (int id) до общедоступных ActionResult Deatils (имя строки). Я как бы пытался избежать этого, но если нет какой-либо опции, то я думаю, что это правильный путь?
2. Зависит. Ожидает ли
{id}
параметр вашего контроллера имя? если это так, то простоnew { id = item.Name }
3. @gdubs: Да, если вы собираетесь идентифицировать материал по его имени, вам, очевидно, потребуется использовать другой запрос, чем если бы вы идентифицировали его по идентификатору. Есть несколько продвинутых приемов привязки, которые вы можете использовать, чтобы обойти это, но я бы сказал, что вы должны упростить это. Если вы хотите использовать идентификатор для удобства, но также хотите включить имя, чтобы оно выглядело красиво, просто включите оба, как указывает Malevolence.
4. @gdubs: Точно. Как вы сказали в своем вопросе, имена должны быть уникальными. Rotten Tomatoes создает уникальную строку ключа для каждого фильма в своей базе данных (например, «footloose-2010»), и они используют этот ключ в URL-адресах вместо цифрового ключа.
5. Со стороны базы данных вы можете просто установить УНИКАЛЬНОЕ ограничение на это поле. В пользовательском интерфейсе вы, вероятно, захотите потребовать от пользователей ввода ключа и проверки кода проверки, чтобы ключ еще не использовался, прежде чем элемент может быть сохранен. Вероятно, вы захотите сделать ключ доступным только для чтения после сохранения элемента, чтобы URL-адреса не менялись.