从 Asp.Net Core 中的 RouteCollection 中删除路由并添加具有相同路由名称的新路由 (nopCommerce-4.00)

Remove route from RouteCollection in Asp.Net Core and add new with same route name (nopCommerce-4.00)

我想从 RouteCollection 中删除现有路由,并想通过插件在 nopCommerce 4.00 中添加具有相同路由名称的新路由

现有路线名称:

//home page
            routeBuilder.MapLocalizedRoute("HomePage", "",
        new { controller = "Home", action = "Index" });

我想将其替换为

   routeBuilder.MapLocalizedRoute("HomePage", "",
    new { controller = "CustomPage", action = "Homepage" });

我尝试了几种方法,但都没有成功。

就我而言,我必须更换robots.txt代。 我在我的插件中创建了一个新的 public 控制器,并将原始操作复制到这里:

public class MiscCommonController : BasePublicController
{
    #region Fields
    private readonly ICommonModelFactory _commonModelFactory;
    #endregion Fields

    #region Ctor
    public MiscCommonController(
        ICommonModelFactory commonModelFactory
        )
    {
        this._commonModelFactory = commonModelFactory;
    }
    #endregion Ctor

    #region Methods
    //robots.txt file
    //available even when a store is closed
    [CheckAccessClosedStore(true)]
    //available even when navigation is not allowed
    [CheckAccessPublicStore(true)]
    public virtual IActionResult RobotsTextFile()
    {
        var robotsFileContent = _commonModelFactory.PrepareRobotsTextFile();
        return Content(robotsFileContent, MimeTypes.TextPlain);
    }
    #endregion Methods
}

之后我为我的插件创建了一个RouteProvider,并将原来的路由替换为我自己的。

public partial class RouteProvider : IRouteProvider
{
    /// <summary>
    /// Gets a priority of route provider
    /// </summary>
    public int Priority => -1;

    /// <summary>
    /// Register routes
    /// </summary>
    /// <param name="routeBuilder">Route builder</param>
    public void RegisterRoutes(IRouteBuilder routeBuilder)
    {
        Route route = null;

        foreach (Route item in routeBuilder.Routes)
        {
            if (item.Name == "robots.txt")
            {
                route = item;
                break;
            }
        }

        if (route != null) routeBuilder.Routes.Remove(route);

        routeBuilder.MapRoute(
            "robots.txt",
            "robots.txt",
            new { controller = "MiscCommon", action = "RobotsTextFile" }
        );
    }
}

就这些了。

这样实现后,路由正常,get请求到达我自己的controller,和原来的一样。

现在,我可以用自己的生成逻辑来替换了。

希望对您有所帮助。

在你插件的 RouteProvider.cs 中写下这些代码(根据你的名字):

var lastExistingRoute= routeBuilder.Routes.FirstOrDefault(x => ((Route)x).Name == "HomePage");
            routeBuilder.Routes.Remove(lastExistingRoute);
            routeBuilder.MapRoute("HomePage", "",
                new { controller = "CustomPage", action = "Homepage", });

以下代码适用于我自己的 4.20 版:

  var lastDownloadRoute=routeBuilder.Routes.FirstOrDefault(x => ((Route)x).Name == "GetDownload");
            routeBuilder.Routes.Remove(lastDownloadRoute);
            routeBuilder.MapRoute("GetDownload", "download/getdownload/{guid}/{agree?}",
                new { controller = "AzTechProduct", action = "GetPayed", });

通过快速检查代码,我发现在 nopCommerce 4.3 中有两种可能的方法来处理这个问题。

首先,您可以创建一个 IRouteProvider,添加与您希望的具有相同签名的路由 'delete' 并确保提供商的优先级大于 1。

这样做基本上会覆盖 Nop 内置的默认路由。这是我的首选方法。

    public partial class RouteProvider: IRouteProvider
    {
        public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
        {

            var pattern = string.Empty;
            if (DataSettingsManager.DatabaseIsInstalled)
            {
                var localizationSettings = endpointRouteBuilder.ServiceProvider.GetRequiredService<LocalizationSettings>();
                if (localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
                {
                    var langservice = endpointRouteBuilder.ServiceProvider.GetRequiredService<ILanguageService>();
                    var languages = langservice.GetAllLanguages().ToList();
                    pattern = "{language:lang=" + languages.FirstOrDefault().UniqueSeoCode + "}/";
                }
            }

            // Handle the standard request
            endpointRouteBuilder.MapControllerRoute("Wishlist", pattern + "wishlist/{customerGuid?}",
                new { controller = "MyShoppingCart", action = "Wishlist" });

            return;
        }

        public int Priority => 100;
    }

上面代码的关键是优先级值。该路由将首先添加到列表中,因此优先于默认路由。使用此技术无需删除默认路由。

第二种可能的方法被证明是行不通的,因为 endpointRouteBuilder.DataSources[n].Endpoints 集合是只读的。因此,据我所知,您无法在添加映射后从该列表中删除映射。