Exception is raised when 2 controller routes and a named action route is used

esam 6 Reputation points
2021-04-07T03:05:56.687+00:00

i have this webapi controller:

using Microsoft.AspNetCore.Mvc;

namespace Crud.Controllers
{
    [ApiController]
    [Produces("application/json")]

    [Route("api/[controller]")]  
    [Route("api/store")] 
    public class PostsController : Controller
    {

        [HttpGet("MyName", Name = "name")] 
        public string GetName()
        {
            return "just my full name";
        }

    }
}

the web application will compile and run OK but an exception will be raised at endpoints.MapControllers(); in startup.cs only when a GET request to "http://localhost:6666/api/posts/myname" is sent...

System.InvalidOperationException: 'The following errors occurred with attribute routing information:

Error 1:
Attribute routes with the same name 'anything' must have the same template:
Action: 'Crud.Controllers.PostsController.GetName (Crud)' - Template: 'api/Posts/MyName'
Action: 'Crud.Controllers.PostsController.GetName (Crud)' - Template: 'api/store/MyName''

exception details

System.InvalidOperationException
HResult=0x80131509
Message=The following errors occurred with attribute routing information:

Error 1:
Attribute routes with the same name 'anything' must have the same template:
Action: 'Crud.Controllers.PostsController.GetName (Crud)' - Template: 'api/Posts/MyName'
Action: 'Crud.Controllers.PostsController.GetName (Crud)' - Template: 'api/store/MyName'
Source=Microsoft.AspNetCore.Mvc.Core
StackTrace:
at Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModelFactory.Flatten[TResult](ApplicationModel application, Func5 flattener) at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorBuilder.Build(ApplicationModel application) at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetDescriptors() at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.OnProvidersExecuting(ActionDescriptorProviderContext context) at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.UpdateCollection() at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.Initialize() at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.GetChangeToken() at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.<>c__DisplayClass11_0.<Subscribe>b__0() at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func1 changeTokenProducer, Action changeTokenConsumer)
at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.Subscribe()
at Microsoft.AspNetCore.Mvc.Routing.ControllerActionEndpointDataSource..ctor(ControllerActionEndpointDataSourceIdProvider dataSourceIdProvider, IActionDescriptorCollectionProvider actions, ActionEndpointFactory endpointFactory, OrderedEndpointsSequenceProvider orderSequence)
at Microsoft.AspNetCore.Builder.ControllerEndpointRouteBuilderExtensions.GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
at Microsoft.AspNetCore.Builder.ControllerEndpointRouteBuilderExtensions.MapControllers(IEndpointRouteBuilder endpoints)
at Crud.Startup.<>c.<Configure>b__5_0(IEndpointRouteBuilder endpoints) in C:\Users\esam\Downloads\JsCrudOperationsDemo\Crud\Startup.cs:line 59
at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
at Crud.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in C:\Users\esam\Downloads\JsCrudOperationsDemo\Crud\Startup.cs:line 57
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass15_0.<UseStartup>b__1(IApplicationBuilder app)
at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
at Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter.<>c__DisplayClass2_0.<Configure>b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__31.MoveNext()

basically the exception happens when more than one route attribute is used on the controller and a named route is used.

how to solve the problem because i can't see any logical problem in using 2 routes that point to one action that is named.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,138 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,199 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. veljkoz 26 Reputation points
    2022-09-14T21:09:41.94+00:00

    To put it differently to what @Jerry Cai-MSFT already explained:

    The solution would be to just delete the "Name" from the HttpGet declaration:
    Instead of:

    [HttpGet("MyName", Name = "name")]   
    

    Put:

    [HttpGet("MyName")]   
    
    1 person found this answer helpful.
    0 comments No comments

  2. Jerry Cai-MSFT 986 Reputation points
    2021-04-07T09:14:39.493+00:00

    Hi,ekanadily

    The error message told you the reason

    Attribute routes with the same name 'anything' must have the same template

    The 'Name' in HttpGet is used to generate the links.Route names must be unique application-wide. check this official site:

    routing

    But the Name in your code will match both api/[controller]/MyName and api/store/MyName.

    So you can delete the Name, or delete one Route on controller.

    Best Regards,

    Jerry Cai
    **
    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. Duane Arnold 3,211 Reputation points
    2021-04-07T09:56:18.387+00:00

    I just like to keep the routing simple and the naming conventions of the CRUD methods simple as well. You can review the WebAPI controllers in the GitHub example solution.

    https://github.com/darnold924/PublishingCompany

    0 comments No comments