Search code examples
c#asp.net-mvc-5asp.net-web-api2asp.net-web-api-routing

web api 2 returning error


I have created a new web api action and have added new routing for it. I am not sure if I have done this right, most probably have not which is why I am getting this error.

So I have added my method/Action like this

    public IQueryable<Devices> GetLatestDevice(DateTime? latestUpdate)
    {
        return db.devices.Where(dev => dev.UpdatedDate > latestUpdate); ;
    }

and this is my routing table

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        //routes.IgnoreRoute("");
        routes.MapRoute(
            name: "Device",
            url: "{controller}/{action}/{lastUpdate}",
            defaults: new { controller = "Home", action = "Index", lastUpdate = UrlParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

and this is how I attempt to get data:

http://localhost:53658/api/DevicesAPI/21-01-2001

    <Error><Message>An error has occurred.</Message><ExceptionMessage>Multiple actions were found that match the request: 
GetLatestDevice on type WhitespiderMonitor.Controllers.DevicesAPIController
GetDevices on type WhitespiderMonitor.Controllers.DevicesAPIController</ExceptionMessage><ExceptionType>System.InvalidOperationException</ExceptionType><StackTrace>   at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()</StackTrace></Error>

My guesses are because the routes are pretty much the same it can't distinguish the two, so my questions really are am I correct in that they are the same, and how would I get it so that it would pick up the date. More information can be provided if needed, thanks!

I have no updated the routes table to

routes.MapRoute(
            name: "Device",
            url: "DevicesAPI/GetLatestDevice/{lastUpdate}",
            defaults: new { lastUpdate = UrlParameter.Optional }
        );

and now get this error:

<Error><Message>The request is invalid.</Message><MessageDetail>The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int64' for method 'System.Web.Http.IHttpActionResult GetDevices(Int64)' in 'WhitespiderMonitor.Controllers.DevicesAPIController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.</MessageDetail></Error>

Solution

  • please replace the action method with the below code.

       public IQueryable<Devices> GetLatestDevice(DateTime latestUpdate)
        {
            return db.devices.Where(dev => dev.UpdatedDate > latestUpdate); 
        }
    

    And Add the below routing code in WebAPIConfig.cs before the default existing routing code.

         Routes.MapHttpRoute(
             name: "CustomApi",
             routeTemplate:"api/{controller}/{action}/{latestUpdate:DateTime?}",
             defaults: new { controller:"DevicesAPI",latestUpdate = RouteParameter.Optional }
                );