1

我正在解决 MVC 3 Web API 中的路由问题。看起来应该很简单,但我没有取得任何进展。

我的错误是:

  <Error>
     <Message>The request is invalid.</Message>
       <MessageDetail>
           The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'Boolean NewViolationsPublished(Int32)' in 'BPA.API.Controllers.CacheManagementController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
       </MessageDetail>
   </Error>

我的 RegisterRoutes 是这样的:

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapHttpRoute(
              name: "NukeAllItemsFromCache",
              routeTemplate: "api/CacheManagement/NukeAllItemsFromCache");


            routes.MapHttpRoute(
                 name: "ControllerAndAction",
             routeTemplate: "api/{controller}/{action}"
             );

            routes.MapHttpRoute(
                 name: "ControllerAndActionAndId",
                 routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional, action = "Get" },
              constraints: new { id = @"^\d+$" } // Only integers 
             );

            routes.MapHttpRoute(
                name: "ControllerAndId",
                routeTemplate: "api/{controller}/{id}",
                  defaults: new { id = RouteParameter.Optional },
          constraints: new { id = @"^\d+$" } // Only integers 
            );
        }

我的控制器是(为了便于阅读,我取出了代码):

 public class CacheManagementController : ApiController
    {
        public CacheManagementController()        

        [HttpGet]
        public bool NewViolationsPublished(int id)

        [HttpGet]
        public bool IsCached(CachedItemLabels label, int clientId)

        [HttpGet]
        public void RemoveItemFromCache(int clientId, CachedItemLabels cacheLabel, string test)

        [HttpGet]
        public string NukeAllItemsFromCache()    
    }

当我尝试调用时出现错误:

http://localhost/api/CacheManagement/NukeAllItemsFromCache

TIA

4

5 回答 5

5

你确定你在正确的地方定义你的路线吗?应使用 System.Web.Http.GlobalConfiguration.Configuration.Routes.MapHttpRoute 配置 Web API 路由(通常在 App_Start 的 WebApiConfig.cs 文件中),如http://www.asp.net/web-api/overview所示/extensibility/configuring-aspnet-web-api,这与 vanilla MVC 使用的路由配置不同。

我想你可能只是在使用默认的 Web API 路由,即 api/{controller}/{id},ID 是可选的。该操作由 HTTP 动词确定,在本例中为 GET,并且您的所有方法都通过 [HttpGet] 匹配。

编辑:示例

全球.asax

 protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        GlobalModifiers.ApplyGlobalConfiguration(this, true);
    }

WebApiConfig.cs

public static class WebApiConfig
{
   public static void Register(HttpConfiguration config)
   {
        config.Routes.MapHttpRoute(
            name: "action-specific",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
    );
}
于 2013-04-11T19:44:23.470 回答
0

我相信你的问题出在这条路上:

routes.MapHttpRoute(
  name: "ControllerAndActionAndId",
  routeTemplate: "api/{controller}/{action}/{id}",
  defaults: new { id = RouteParameter.Optional, action = "Get" },
  constraints: new { id = @"^\d+$" } // Only integers 
);

您指定id为可选参数,同时将其约束为实际上不可为空的数字。如果/api/CacheManagement/NukeAllItemsFromCache是一个例外,则为它添加额外的路线,否则@"^\d*$"如果可能的话,将约束放宽到类似的东西。

于 2013-04-11T19:19:28.000 回答
0

您尝试将参数 id 设置为可为空,例如:

[HttpGet]
public bool NewViolationsPublished(int? id)

或者

    [HttpGet]
    public bool NewViolationsPublished(Nullable<Int32> id)

也许这行得通...

于 2013-06-19T17:10:05.863 回答
0

您缺少配置的路由的默认操作:

routes.MapHttpRoute(
          name: "NukeAllItemsFromCache",
          routeTemplate: "api/CacheManagement/NukeAllItemsFromCache");

应该

routes.MapHttpRoute(
          name: "NukeAllItemsFromCache",
          routeTemplate: "api/CacheManagement/NukeAllItemsFromCache",
          defaults: new { action = "NukeAllItemsFromCache" }
);
于 2013-04-12T13:04:44.393 回答
0

仔细检查您的控制器是否扩展了 ApiController 而不是 Controller

 public class CacheManagementController : ApiController

而不是

 public class CacheManagementController : Controller
于 2015-02-10T16:56:42.753 回答