我想弄清楚它是如何工作的,例如,如果我拉起一个类别页面:http:// localhost:15536 / desktops,它将在CatalogController中命中以下Action方法:
public virtual IActionResult Category(int categoryId, CatalogPagingFilteringModel command)
那么如何传递正确的类别ID(int),但它不是URL的一部分,它如何工作?
在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产品或类别,等等)。该EntityId
指示Id
尖实体(IG Id
的Product
)。在Slug
表明什么网址可以达到预期的实体。在您的示例中,EntityName
“类别” EntityId
是Id
该类别的和Slug
是“桌面”。
那么,Nopcommerce如何将这些路由Slug
到正确的Controller and Action?为了弄清楚这一点,我们必须查看GenericPathRoute
位于Nop.Web.Framework \ Seo \ GenericPathRoute.cs中的类。这个类被注册为一个自定义Route
的IRouteBuilder
。无论asp.net核心路由和Nopcommerce详细信息如何,在每次请求开始时都会调用的RouteAsync
方法GenericPathRoute
。如果我们研究这种方法,我们可以看到本节(在本节之前,urlRecord
是从那里从数据库中提取的Slug
,因此我们知道什么是实体及其实体Id
,因此我们可以将其正确地路由到所需的Controller and Action上。参数):
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命令中命名的实体有效。