В Nopcommerce есть сущность с именем UrlRecord
, вы можете найти ее в Nop.Core \ Domain \ Seo \ UrlRecord.cs:
public partial class UrlRecord : BaseEntity
{
public int EntityId { get; set; }
public string EntityName { get; set; }
public string Slug { get; set; }
public bool IsActive { get; set; }
public int LanguageId { get; set; }
}
EntityName
указывает, что это UrlRecord
используется для какого объекта (ig Продукт или Категория и т. Д. c.). EntityId
указывает, что Id
указывает на сущность (ig Id
из Product
). Slug
указывает, что с помощью какого URL мы можем достичь намеченного объекта. В вашем примере EntityName
- это «Категория», EntityId
- это Id
категории, а Slug
- это «рабочий стол».
Итак, как Nopcommerce направляет эти Slug
на нужный контроллер и действие? Чтобы понять это, мы должны взглянуть на класс GenericPathRoute
, который находится в Nop.Web.Framework \ Seo \ GenericPathRoute.cs. Этот класс зарегистрирован как пользовательский Route
для IRouteBuilder
. Независимо от asp. net основной маршрутизации и деталей Nopcommerce, RouteAsync
метод GenericPathRoute
вызывается в начале каждого запроса. Если мы взглянем на этот метод, мы увидим этот раздел (перед этим разделом urlRecord
выбирается из базы данных Slug
, поэтому мы знаем, что такое сущность и ее Id
, поэтому мы можем направить это к желаемому контроллеру и действию с правильными аргументами):
var currentRouteData = new RouteData(context.RouteData);
switch (urlRecord.EntityName.ToLowerInvariant())
{
case "product":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Product";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "ProductDetails";
currentRouteData.Values[NopPathRouteDefaults.ProductIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "producttag":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Catalog";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "ProductsByTag";
currentRouteData.Values[NopPathRouteDefaults.ProducttagIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "category":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Catalog";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "Category";
currentRouteData.Values[NopPathRouteDefaults.CategoryIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "manufacturer":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Catalog";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "Manufacturer";
currentRouteData.Values[NopPathRouteDefaults.ManufacturerIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "vendor":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Catalog";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "Vendor";
currentRouteData.Values[NopPathRouteDefaults.VendorIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "newsitem":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "News";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "NewsItem";
currentRouteData.Values[NopPathRouteDefaults.NewsItemIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "blogpost":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Blog";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "BlogPost";
currentRouteData.Values[NopPathRouteDefaults.BlogPostIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
case "topic":
currentRouteData.Values[NopPathRouteDefaults.ControllerFieldKey] = "Topic";
currentRouteData.Values[NopPathRouteDefaults.ActionFieldKey] = "TopicDetails";
currentRouteData.Values[NopPathRouteDefaults.TopicIdFieldKey] = urlRecord.EntityId;
currentRouteData.Values[NopPathRouteDefaults.SeNameFieldKey] = urlRecord.Slug;
break;
default:
//no record found, thus generate an event this way developers could insert their own types
EngineContext.Current.Resolve<IEventPublisher>()
?.Publish(new CustomUrlRecordEntityNameRequestedEvent(currentRouteData, urlRecord));
break;
}
context.RouteData = currentRouteData;
Здесь мы можем видеть, что он изменяет routeData этого запроса относительно EntityName
. Здесь мы видим, что эта функция будет работать только для сущностей, названных в этой команде switch / case.