Маршрутизация URL в NOP Commerce - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь выяснить, как это работает, например, если я открываю страницу категории: http://localhost: 15536 ​​/ desktops , она попадает в следующий метод Action в CatalogController:

public virtual IActionResult Category(int categoryId, CatalogPagingFilteringModel command)

Итак, как он передает правильный идентификатор категории (int), но не является частью URL, как это работает?

1 Ответ

1 голос
/ 11 апреля 2020

В 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.

...