简体   繁体   中英

NET Core 5 How to override an action on a controller

Let's imagine I have a " platform " with some basic features. It has its own set of controllers with actions delivered as a class library. For example, let's name it as CartController with Order action, as a result, API URL will be Cart/Order .

For some reason, I want to extend logic in Order process, I added MyCartController with Order action in my project where I reference the platform . Now I need to set up the app to use my custom action instead of the original one.

In ASP MVC 5 (based on .NET Framework) I can do it as follows

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var route = new Route("Cart/Order", new RouteValueDictionary(new Dictionary<string, object>
        {
            { "action", nameof(MyCartController.Order) },
            { "controller", nameof(MyCartController).Replace("Controller", "") }
        }), new MvcRouteHandler());

        routes.Insert(RouteTable.Routes.Count - 2, route);
    }
}

and then call it from Startup as

public override void Configuration(IAppBuilder builder)
{
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

and it worked well.

But after migration to .Net Core 5, it stopped working. In Startup, I added

public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
        app.UseRouting();
        app.UseEndpoints(endpoints => 
        {
            endpoints.MapControllerRoute("MyCartOrder", "Cart/Order", new { controller = nameof(MyCartController).Replace("Controller", ""), action = nameof(MyCartController.Order) });
        });
}

with no luck. It looks like they broke something helpful here https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/Routing/ControllerActionEndpointDataSource.cs#L100

I tried to decorate my controller with Route("Cart") attribute and HttpPost("Order") with AmbiguousMatchException: The request matched multiple endpoints exception.

I have no idea of how to override it then.

So my question is: How to override the route to use my action on my controller in .Net Core 5? What is the equivalent of routes.Add from .Net 4.8 which works for URL matching but not only for links generation?

Any thoughts and ideas will be appreciated.

You can mark the needed action in the "override" controller with Http{Method}Attribute and set Order property to some value (by default -1 should do the trick):

[HttpPost("Order", Order = -1)]

HttpMethodAttribute.Order Property:

Gets the route order. The order determines the order of route execution. Routes with a lower order value are tried first. When a route doesn't specify a value, it gets the value of the Order or a default value of 0 if the RouteAttribute doesn't define a value on the controller.

Or set the property with the same name of RouteAttribute on the controler:

[Route("Cart", Order = -1)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM