Я пытаюсь найти лучший способ сгенерировать названия продуктов в URL-адресе. Поэтому вместо того, чтобы представлять продукты по их идентификатору, я хотел бы, чтобы они были названы.
Например: https: // localhost: 44233 / Товары / Подробности / Яблоки
вместо того
https: // localhost: 44233 / Products / Detail / 2
Пока что я изменил свой шаблон маршрутизации в моем файле StartUp.cs со значения по умолчанию на тот, который я опубликовал ниже. Не получилось.
Любые предложения о том, как это исправить, помогут!
StartUp.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Products",
template: "{controller=Products}/{action=Detail}/{name}"
);
});
Model
public class ProduceDetailVM
{
public int Id {get; set;}
public string ProduceName {get;set;}
public string ProducePrice {get;set;}
public string ProduceDescription {get;set;}
}
Products Controller
public async Task<IActionResult> Detail(int Id, string name)
{
var produceDetail = repoService.GetById(Id);
var produceName = repoService.GetByProduceName(name);
var produceModel = new ProduceDetailVM()
{
Id = produceDetail.Id,
ProduceName = produceName.Name,
ProducePrice = produceDetail.Price,
ProduceDescription = produceDetail.Description
};
return View(produceModel);
}
RepoService
public class RepoService: IRepository
{
public ProductsTable GetById(int Id)
{
return _context.ProductsTable.Where(i => i.Id == Id).First();
}
public ProductsTable GetByProduceName(string name)
{
return _context.ProductsTable.Where(p => p.ProduceName == name).FirstOrDefault();
}
}
IRepository
public interface IRepository
{
ProductsTable GetById(int Id);
ProductsTable GetByProduceName(string name);
}
Detail View
<html>
<head>
<title>Detail Page</title>
</head>
<body>
<div class = "container-fluid">
<span class = "image card" style = "background-image:url(produceDetail.ProductImage)"></span>
<div class = "center">
<a class = "button" asp-controller = "Products" action = "Detail" asp-route-id = "@produceDetail.ProduceName">View More</a>
</div>
</div>
</body>
</html>
Спасибо за это, Дэн. К сожалению, название товара не уникальное. Есть ли другие способы, с которыми я не знаком?
Другого подхода к этому нет. Если вы хотите получить доступ к продуктам с использованием идентификатора (Id
или name
), этот идентификатор должен быть уникальным. Либо придерживайтесь Id
, либо обновите свои данные, чтобы name
был уникальным.
Имеет смысл. Есть ли способ включить как идентификатор, так и имя? то есть localhost: 43222 / Продукты / Подробности / 2 / Apple Как бы это сделать? Атрибут маршрута? или отображение маршрута в startup.cs?
So far, I've changed my routing template in my StartUp.cs
И, таким образом, полностью игнорирует то, что это похоже на устаревшую технологию в течение многих лет.
Маршрутизация атрибутов позволяет вам определять собственные маршруты для каждого действия на каждом контроллере. Для этого особенно оптимизировано ядро dotnet (с новым механизмом маршрутизации в версии 2.2, которая выходит в этом году).
Спасибо, что обратили на это мое внимание. Как бы это выглядело? Будет ли это работать: [Маршрут ("Продукты / Деталь / имя")] или [Маршрут ("Продукты / Деталь / {имя}")]
Второй. Не уверен, что это хорошая идея - специальные символы в URL-адресах проблематичны, локализация может быть большой проблемой. Я обычно избегаю того подхода, который вы хотите использовать. О, и читайте в своем IRepository - антипаттерне.
Спасибо, Том. Я посмотрю на irepo anipattern. Второй атрибут маршрута у меня не работал. ; (
Вы по-прежнему используете параметр
Id
вDetail()
, что приведет к ошибке, если вы больше не будете передаватьId
по маршруту. Если вы хотите просмотреть подробную информацию о продукте, используя только имя, вы должны получить все сведения о продукте черезname
, и каждый продукт должен иметь уникальныйname
.