为什么我的Web API RESTful路由会抛出404错误?

时间:2015-04-21 15:54:48

标签: c# asp.net-mvc rest asp.net-web-api

在我正在开发的一个副项目上,我正在使用WebAPI 2.2创建一个RESTful API。我正在研究的是一种访问游戏设置的方法。我想要完成的路线的一个例子如下:

http://x/api/GameSettings/             <-- Returns all settings
http://x/api/GameSettings/audio        <-- Returns the 'audio' category
http://x/api/GameSettings/audio/volume <-- Returns the key 'volume' in category audio

注意:这些示例都是Get个请求。

我已经实现了以下控制器...

public class GameSettingsController : ApiController
{
    // GET /api/GameSettings
    public HttpResponseMessage Get()
    {
        // Magic
        return Request.CreateResponse(HttpStatusCode.OK, model);
    }

    public HttpResponseMessage Get(string category)
    {
        // Similar.
    }

    public HttpResponseMessage Get(string category, string key)
    {
        // Slightly different, but still similar.
    }
}

我绑定了以下MVC路线:

// Only necessary for the main view...
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}",
    defaults: new { controller = "Home", action = "Index" }
);

并且,我绑定了以下WebAPI路由:

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
    name: "ApiGeneralCommand",
    routeTemplate: "api/{controller}",
    defaults: new { controller = "GameSettings" }
);

config.Routes.MapHttpRoute(
    name: "ApiCategoryCommands",
    routeTemplate: "api/{controller}/{category})",
    defaults: new { controller = "GameSettings" }
);

config.Routes.MapHttpRoute(
    name: "ApiKeyCommands",
    routeTemplate: "api/{controller}/{category}/{key}",
    defaults: new { controller = "GameSettings", category = "master" },
    constraints: new { key = "[a-z0-9.-]" }
);  

...最后,我的Global.asax配置设置如下:

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

......但是一个小问题。

当我导航到http://x/api/GameSettings/audio时,出现404错误。就好像请求中的category参数没有与我的控制器上的Get(string category)方法正确关联。这让我相信我的路线错了或者我错过了什么。

作为一个健全性检查,我使用非RESTful语法http://x/api/GameSettings?category=audio测试了该路由,该语法命中了一个断点并产生了结果。这只是重申了我的理论,即WebAPI路由已关闭。

作为额外的健全性检查,我测试了http://x/api/GameSettings/,不仅点击了该函数中设置的断点,还返回了预期的结果。

问题:我的路由丢失了什么,这会让http://x/api/GameSettings/audio像[{1}}一样工作?我有一段时间没有使用RESTful API,所以我确定我错过了一些非常愚蠢的东西。

2 个答案:

答案 0 :(得分:2)

更改顺序并尝试。因为ASP.NET意识到您有三条路线。它将首先检查最顶层的路线,如果您的数据可以放在该路线中,则不会再检查任何路线。

config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "ApiKeyCommands",
        routeTemplate: "api/{controller}/{category}/{key}",
        defaults: new { controller = "GameSettings", category = "master" },
        constraints: new { key = "[a-z0-9.-]" }
    ); 

    config.Routes.MapHttpRoute(
        name: "ApiCategoryCommands",
        routeTemplate: "api/{controller}/{category})",
        defaults: new { controller = "GameSettings" }
    );

    config.Routes.MapHttpRoute(
        name: "ApiGeneralCommand",
        routeTemplate: "api/{controller}",
        defaults: new { controller = "GameSettings" }
    );

答案 1 :(得分:2)

我会尝试使用属性路由。我相信这应该适合你的情况。

[RoutePrefix("api/GameSettings")]
public class GameSettingsController
{
    // GET /api/GameSettings
    [HttpGet]
    public HttpResponseMessage Get()
    {
        // Magic
        return Request.CreateResponse(HttpStatusCode.OK, model);
    }

    [Route("{category}")]
    [HttpGet]
    public HttpResponseMessage Get(string category)
    {
        // Similar.
    }

    [Route("{category}/{key}")]
    [HttpGet]
    public HttpResponseMessage Get(string category, string key)
    {
        // Slightly different, but still similar.
    }
}

我会删除你添加到配置中的内容。

希望这有帮助。