【问题标题】:WebAPI2 attribute based routing 404 with nested route基于 WebAPI2 属性的路由 404 与嵌套路由
【发布时间】:2015-10-05 22:22:45
【问题描述】:

我知道有很多(已回答)与基于属性的路由相关的问题,但我似乎找不到一个可以回答我的特定场景的问题。

我有一个 WebAPI 2 控制器,有几个使用默认路由的方法:

public Dictionary<int, SensorModel> Get()
{
    return SensorModel.List();
}

public SensorModel Get(int id)
{
    return SensorModel.Get(id);
}

[HttpPost]
public SensorModel Post(SensorModel model)
{
    if (model == null) throw new Exception("model cannot be null");
    if (model.Id <= 0) throw new Exception("Id must be set");
    return SensorModel.Update(model.Id, model);
}

这些都可以正常工作。我正在尝试创建如下嵌套路由:

[Route("sensor/{id}/suspend")]
public SensorModel Suspend(int id, DateTime restartAt, EnSite site)
{
    return SensorModel.Suspend(id, restartAt, site);
} 

我希望 URL 看起来像这样:

http://[application_root]/api/sensor/1/suspend?restartAt={someDateTime}&site={anInt}

抱歉,忘了说实际问题是 404! 谁能告诉我我做错了什么?我知道我可以这样做:

[Route("sensor/suspend")]
public SensorModel Suspend(int id, DateTime restartAt, EnSite site)
{
    return SensorModel.Suspend(id, restartAt, site);
}

这使得网址:

http://[application_root]/api/sensor/suspend?id=1&restartAt={someDateTime}&site={anInt}

但我认为,更简洁的 API 设计似乎是嵌套路由。

【问题讨论】:

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


    【解决方案1】:

    在这一点上你的假设是错误的:

    For which I would expect the URL to look like:
    
    http://[application_root]/api/sensor/1/suspend?restartAt={someDateTime}&site={anInt}
    

    应该是这样的:

    http://[application_root]/sensor/1/suspend?id=1&restartAt={someDateTime}&site={anInt}
    

    当您指定基于属性的路由时,它会覆盖默认路由架构 ../api/..(或您在 route.config 文件中指定的任何内容)。

    因此,无论何时您尝试使用基于属性的路由,您都应该执行/route_prefix_at_controller_level/route_prefix_at_method_level 之类的操作。

    【讨论】:

    • 好的,如果我丢失了前导的“/api”,它应该可以工作 - 但如果我必须在查询字符串中包含“id”参数,路由仍然没有正确嵌套,我想要的是从 URL 的前面提取它,就像 angular-ui-router 之类的东西一样 - 有什么想法吗?
    • @JamieS:我相信,你正在寻找这样的东西:[Route("sensor/suspend/{id}/{someDateTime}/{int}")]。像这样修改你的路线并注意:只有当每件事(id,datetime,int)都存在时,这条路线才会被匹配。所有字段均为必填项。
    • 啊,好吧,所以 WebAPI 路由无法让模式为“sensor/{id}/suspend/{someDateTime}/{int}”?
    • @JamieS:我的意思是这样做是有效的,而且完全有可能,但是所有[id, someDateTime, int] 的项目都必须在Url 中提供。
    • 这很好,只是为了确认一下,因为我的 URL 和你的不同:参数不必都在 URL 的末尾,“id”一个可以在另外两个之间我有它的元素吗?
    猜你喜欢
    • 2014-01-12
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2014-09-17
    • 1970-01-01
    • 2011-01-15
    • 2014-02-12
    相关资源
    最近更新 更多