Search code examples
c#asp.net-web-api-routingasp.net-web-api2

Custom routing in Web API 2. Failing to reach controller method


I have a method inside of my controller which I am trying to reach:

[HttpPost, ActionName("UpdateTitle")]
public IHttpActionResult UpdateTitle(Guid playlistId, string title)
{
    using (ITransaction transaction = Session.BeginTransaction())
    {
        PlaylistManager.UpdateTitle(playlistId, title);

        transaction.Commit();
    }

    return Ok();
}

I have another method in the controller which is also a POST and is the method which is actually being hit by my request (erroneously):

[HttpPost]
public PlaylistDto Create(PlaylistDto playlistDto)

Here's what my raw request information looks like:

enter image description here

Here's my routing:

public static class WebApiConfig
{
    //  TODO: Create test cases for custom routing.
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Routes.MapHttpRoute("UpdateTitle", "Playlist/UpdateTitle/{playlistId}/{title}");

        //  TODO: What does this do?
        // Web API routes
        //config.MapHttpAttributeRoutes();

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

    }
}

Why on earth is it redirecting to the Create method? The signature looks correct to me for being routed to the UpdateTitle method.


Solution

  • First you need to create a class that contains all your form data. You may be able to use your PlaylistDto class for this:

    public class PlaylistDto
    {
        public Guid PlaylistId { get; set; }
        public string title { get; set; }
    }
    

    Then change your UpdateTitle method to:

    [HttpPost, ActionName("UpdateTitle")]
    public IHttpActionResult UpdateTitle(PlaylistDto Dto)
    {
        using (ITransaction transaction = Session.BeginTransaction())
        {
            PlaylistManager.UpdateTitle(Dto.playlistId, Dto.title);
    
            transaction.Commit();
        }
    
        return Ok();
    }
    

    Finally change your routing as follows:

    public static class WebApiConfig
    {
        //  TODO: Create test cases for custom routing.
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            config.Routes.MapHttpRoute(
                name: "UpdateTitle",
                routeTemplate: "Playlist/UpdateTitle",
                defaults: new { controller = "PlaylistController", action = "UpdateTitle" }
             );    
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    
        }
    }