C# 为什么我的WebAPI RESTful路由抛出404错误?

C# 为什么我的WebAPI RESTful路由抛出404错误?,c#,asp.net-mvc,rest,asp.net-web-api,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/a

在我正在进行的一个附带项目中,我正在使用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
我绑定了以下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
http://x/api/GameSettings?category=audio
?我已经有一段时间没有使用RESTful API了,所以我确信我错过了一些非常愚蠢的东西。

更改顺序并尝试一下。因为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" }
    );

我会尝试使用属性路由。我相信这对你的情况来说应该很有效

[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.
    }
}
我将删除您添加到配置中的内容


希望这能有所帮助。

不幸的是,这不起作用;当我尝试
http://x/api/GameSettings/audio
。我可能错过了一些其他的东西,但这是一个很好的信息,我忘记了它是一个优先系统。我不知道这是一个东西!更有用的信息。我需要更频繁地实现API。但是,这会使404出现在所有内容中,包括
/api/GameSettings
路径。是否有任何其他必要的配置使其工作?我将在这里查看更多信息:它非常有用,易于使用,可配置。你怎么把这些叫做404?另外,在重构之后,api路由配置文件是什么样子的?你的帖子对我遗漏的内容没有太大帮助。我正在运行这个项目,它将打开我的
主页/索引
页面。为了测试我的API,我手动输入
http://localhost:port/api/GameSettings
。按Enter键时,应该发生的事情(至少在IE中)是从服务器下载一个.json文件。重构后,
WebApiConfig.Register(HttpConfiguration)
方法中剩下的就是
config.maphttpAttribute路由()您的项目中也有MVC吗?如果是这样,我发现必须在mvc路由配置之前调用ApiRoute config。我认为您的问题可能是,您需要公共类游戏设置控制器:ApiController
[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.
    }
}