asp.net webapi 2属性路由无法正常工作

时间:2013-11-11 13:09:37

标签: asp.net-web-api asp.net-web-api-routing

我使用.net framework 4.5安装了使用mvc4的visual studio 2012。现在我想使用webapi2进行属性编写,我希望我的hlep页面能够正确显示所有端点。

在我的解决方案中,我添加了一个新的mvc4基础emtpy项目并使用nuget i升级到mvc5,然后我安装了webapi2软件包。最后我已经为webapi2安装了帮助包。

现在当我使用routeprefix时,我无法在帮助页面上看到任何内容,当我尝试在浏览器中访问我的webapi端点时,它会抛出以下错误。

http://expressiis.com/api/v1/

   <Error>
    <Message>
    No HTTP resource was found that matches the request URI 'http://expressiis.com/api/v1/'.
    </Message>
    <MessageDetail>
    No type was found that matches the controller named 'v1'.
    </MessageDetail>
    </Error>

namespace WebApi.Controllers
{
    [RoutePrefix("api/v1")]
    public class SubscribersController : ApiController
    {
        // GET api/<controller>   
        [Route("")]
        [HttpGet]
        public IQueryable<string> Get()
        {
            return new string[] { "value1", "value2" }.AsQueryable();
        }


    }
}

8 个答案:

答案 0 :(得分:48)

根据您的信息,您似乎没有拨打httpConfig.MapHttpAttributeRoutes()(确保在任何传统路由注册之前调用此

由于您尚未调用MapHttpAttributeRoutes,因此您的请求似乎与传统路由匹配,例如api/{controller}。这不起作用,因为匹配传统路线的路线永远不会看到用属性路线装饰的控制器/动作。

答案 1 :(得分:34)

我遇到的一个问题与Application_Start()中的排序有关。请注意以下Web API配置的顺序:

这不起作用

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

这确实有效

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

答案 2 :(得分:16)

我也遇到了这个问题,经过长时间的搜索,我意识到我使用的是System.Web.Mvc.RouteAttribute而不是System.Web.Http.RouteAttribute 在纠正此问题并使用config.MapHttpAttributeRoutes() everything worked fine.

之后

答案 3 :(得分:9)

这不是你的情况(从你的示例代码中可以看出),但请记得用http://bar.com/login?new_key=some_value 结束Controller类名。

否则Controller将无法接听。

答案 4 :(得分:4)

这个问题已经有了一个选定的答案。但我对自己有一个不同的解决方案,并认为如果所选答案没有帮助,回复将会有所帮助。

对我来说这是一个愚蠢的错误。我有两个控制器,但只有一个工作。解决方案是我的控制器类命名不正确!

我的工作负责人 -

public class FooController : ApiController { }

我的非工作控制器 -

public class BarControllers : ApiController { }

确保您的控制器类以Controller结尾。尾随s让我了!

答案 5 :(得分:0)

在我的情况下,VS使用名称

创建我的控制器
TestController1

我不知道他为什么把这个数字和#34;一个&#34;在名称的末尾,但删除并将工作。

答案 6 :(得分:0)

确保您没有两个名称相同的控制器!我将一些控制器从一个我扔掉的程序集中移到了网站中……而该网站不再引用其他程序集所引用的旧程序集,这意味着它将被复制到WebSite的bin文件夹中。然后,当发现两次出现同一控制器时,路由发现过程似乎会无声地失败!

答案 7 :(得分:0)

就我而言,我在属性中缺少完整的自定义路径。我只写了没有“ api /”的自定义操作名称。所以那是我的错误。我的情况是 WebApiConfig模板代码:

        // Web API routes
        config.MapHttpAttributeRoutes();

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

我不正确的路线

[RoutePrefix("myapps")]  // wrong code
public class AppsController : BaseRestAPIController
{
    [HttpPost]
    [Route("getapps")]
    public ResponseData GetAppList()
    {

正确的方式

[RoutePrefix("api/myapps")]  // correct way. full path start from 'api/'
public class AppsController : BaseRestAPIController
{
    [HttpPost]
    [Route("getapps")]
    [Route("api/myapps/getapps")] // you can use full path here, if you dont want controller level route
    public ResponseData GetAppList()
    {