简体   繁体   中英

Webapi custom route action

Situation :

I've created controller class that extends ApiController and includes following methods :

        // GET api/Posts/5
        [ResponseType(typeof(Post))]
        public IHttpActionResult GetPost(int id)
        {
           ...
        }

        // GET api/Posts/ByBoardID/2
        [HttpGet]
        [ActionName("ByBoardID")]
        public IQueryable<Post> GetByBoardID(int boardID)
        {
           ...
        }

The idea is to match those method to a given routes (ie 'api/Posts/ByBoardID/2' to a GetByBoardID(int boardID) method and 'api/Posts/2' to a GetPosts(int id) method).

Here's route config :

    config.Routes.MapHttpRoute(
        name: "ByParamApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional });

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional });

Problem :

Second route ('api/Posts/ByBoardID/2') cannot be matched - No HTTP resource was found that matches the request URI .

Question :

Whats the best practice to create such 'nested' routes inside controller? I will use many controllers with the same pattern (/{controller}/{id} and /{controller}/bySpecialParam/{id}) so I don't want to 'hardcode' such route that won't be reusable.

Only way I ever got working such combination is by changing this

[ActionName("ByBoardID")]

to

[Route("api/Posts/ByBoardID/{boardID}")]

Never able to figure out how the ActionName attribute works so always preferred to go with Route attribute

This worked:

1) Provide actionName for both the methods in the controller.

[ActionName("DefaultAction")]
[ActionName("ByBoardID")]

2) In the webapiconfig class, add the following routes

config.Routes.MapHttpRoute(
                "defaultActionRoute",
                "{controller}/{action}/{id}",
                null,
                new
                {
                    action = "ByBoardId"
                });
            config.Routes.MapHttpRoute(
                "defaultRoute",
                "{controller}/{id}",
                new
                {
                    action = "DefaultAction"
                });

Make sure you have the GlobalConfiguration.Configuration.EnsureInitialized(); at the end of Application_Start() method.

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