【问题标题】:Why do my WebAPI RESTful routes throw 404 errors?为什么我的 WebAPI RESTful 路由会抛出 404 错误?
【发布时间】:2015-04-21 15:54:48
【问题描述】:

在我正在处理的一个副项目中,我正在使用 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/audiohttp://x/api/GameSettings?category=audio 一样工作?我有一段时间没有使用 RESTful API,所以我确定我错过了一些非常愚蠢的东西。

【问题讨论】:

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


    【解决方案1】:

    我会尝试使用属性路由。我相信这应该适用于您的场景。

    [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.
        }
    }
    

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

    希望这会有所帮助。

    【讨论】:

    • 我不知道这是一件事!更多有用的信息。我需要更频繁地实现 API。但是,这会使 everything 出现 404,包括 /api/GameSettings 路径。是否需要任何其他配置才能使其正常工作?
    • 我会在这里查看更多信息:asp.net/web-api/overview/web-api-routing-and-actions/… 它非常有用且易于使用,可配置。你在做什么来调用这些你得到一个 404?另外,在你重构之后,你的 api 路由配置文件是什么样的?
    • 您的帖子对我所缺少的内容并没有太大帮助。我正在运行该项目,这将打开我的Home/Index 页面。为了测试我的 API,我手动输入 http://localhost:port/api/GameSettings。按下 Enter 后,应该会发生什么(至少在 IE 中)是从服务器下载一个 .json 文件。重构之后,WebApiConfig.Register(HttpConfiguration) 方法中剩下的就是config.MapHttpAttributeRoutes();
    • 你的项目中也有 MVC 吗?如果是这样,我发现他们的 ApiRoute 配置必须在 mvc 路由配置之前调用
    • 我认为你的问题可能是这个,你需要公共类 GameSettingsController : ApiController
    【解决方案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" }
        );
    

    【讨论】:

    • 不幸的是,这不起作用;当我尝试http://x/api/GameSettings/audio 时,我仍然得到 404。我可能还遗漏了其他内容,但这是很棒的信息,我忘记了这是一个优先系统。
    猜你喜欢
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    相关资源
    最近更新 更多