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

3.8k Views Asked by At

I want to remove existing route from RouteCollection and want to add new route with same route name in nopCommerce 4.00 via plugin

Existing route name:

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

I Want to replace it with

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

I tried several ways but not get any luck.

3

There are 3 best solutions below

3
On BEST ANSWER

In my case, I have to replace the robots.txt generation. I created a new public controller in my plugin, and I copy the original action here:

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
}

After this I create a RouteProvider for my plugin, and I replaced the original route to my own one.

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" }
        );
    }
}

That's all.

After this implementation, the routing works fine, and the get request landed in my own controller, which is act like the original.

Now, I can replace the generation logic with my own.

I hope it helps.

4
On

in the RouteProvider.cs of your plugin write these codes (based on your names):

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

and the below codes worked for myself version 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", });
1
On

There are two potential ways to deal with this in nopCommerce 4.3 that I see with a quick examination of the code.

First, you could create an IRouteProvider, add your route that has the same signature as the one you wish to 'delete' and make sure the Priority on the provider is greater than 1.

Doing this will basically override the default route built into Nop. This is my preferred method.

    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;
    }

The key to the code above is the Priority value. This route will get added to the list first and will therefore take precedence over the default route. Using this technique eliminates the need to delete the default route.

The second possible method turns out to not work because the endpointRouteBuilder.DataSources[n].Endpoints collection is read only. So, as far as I know, you can't remove mappings from that list after they have been added.