web api 2 返回错误

web api 2 returning error

我创建了一个新的网络 api 操作并为其添加了新的路由。我不确定我是否做对了,很可能没有,这就是我收到此错误的原因。

所以我已经像这样添加了我的 method/Action

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

这是我的路由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 }
        );

这就是我尝试获取数据的方式:

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>

我的猜测是因为路线几乎相同所以无法区分两者,所以我的问题真的是我是否正确,因为它们是相同的,我如何获得它以便它会选择更新日期。如果需要可以提供更多信息,谢谢!

我没有更新路线 table 到

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

现在出现此错误:

<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>

您有两条通用路线。您可以将其中一个更改为:

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

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

所以使用Device控制器时会命中特定的一个。

另一种解决方案是在您的路由代码中添加 action 参数,例如:

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

您需要在 url 中传递 action 名称,如下所示:

http://localhost:53658/api/DevicesAPI/{your action name}/21-01-2001

你的路线应该是这样的:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        //routes.IgnoreRoute("");
        routes.MapRoute( name: "DevicesAPIRoute", 
                          url:"DevicesAPI/GetLatestDevice/{latestUpdate}", 
                          defaults: new { controller = "DevicesAPI", action = "GetLatestDevice", lastUpdate = UrlParameter.Optional } ); 

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

请将操作方法​​替换为以下代码。

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

并在WebAPIConfig.cs中的默认现有路由代码之前添加以下路由代码。

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