【问题标题】:Multiple GET actions多个 GET 操作
【发布时间】:2013-07-19 21:32:32
【问题描述】:

我正在创建以下控制器:

public FoosController : ApiController
{
    public IQueryable Get()
    {
        return AnODataQueryableListOfFoos();
    }

    public void Delete(Guid id)
    {
        DeleteTheFooWithId(id);
    }

    public IQueryable<Bar> GetBars(Guid id)
    {
        var foo = GetFooById(id);
        return AnODataQueryableListOfBarsForThisFoo(foo);
    }

    public IEnumerable ProjectedBars(Guid id)
    {
        var foo = GetFooById(id);
        return foo.Qux
            ? OneProjectionOfBars(foo)
            : AnotherProjectionOfBars(foo);
    }
}

(可以将 Bars 的列表视为 Foo 的“内容”...)

我打算使用以下网址:

GET /api/Foos                         -> Get
GET /api/Foos/SOME_GUID/Bars          -> GetBars
GET /api/Foos/SOME_GUID/ProjectedBars -> GetProjectedBars
DELETE /api/Foos/SOME_GUID            -> Delete

我尝试了[ActionName] 和自定义路由的几种组合,但总是出现冲突或 404。

让这个工作最简单的方法是什么?如果可能的话,我想保持我的路线通用(即没有特定于控制器的东西)。其他控制器使用更标准的/Stuff - Stuff/id 方法。

我也愿意接受指出我完全滥用 URL 的人。欢迎改进。

【问题讨论】:

  • 你考虑过属性路由吗?最新的 webapi 作为对其的内置支持。你可以在这里阅读更多信息:asp.net/web-api/overview/web-api-routing-and-actions/…
  • @KiranChalla 我已经考虑过了。主要问题:它还不稳定。我也倾向于更喜欢基于约定的实现。而且我愿意让我的设计适应标准约定或稍微调整一下约定。

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


【解决方案1】:

我同意属性路由是最好的方法,但是您可以尝试以下方法:

public FoosController : ApiController
{
    [HttpGet]
    public IQueryable Get()
    {
        return AnODataQueryableListOfFoos();
    }

    [HttpGet]
    [ActionName("Bars")]
    public IQueryable<Bar> GetBars(Guid id)
    {
        var foo = GetFooById(id);
        return AnODataQueryableListOfBarsForThisFoo(foo);
    }

    [HttpGet]
    [ActionName("ProjectedBars")]
    public IEnumerable GetProjectedBars(Guid id)
    {
        var foo = GetFooById(id);
        return foo.Qux
            ? OneProjectionOfBars(foo)
            : AnotherProjectionOfBars(foo);
    }
}

然后使用以下路线:

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

config.Routes.MapHttpRoute(
    name: "DefaultApi2",
    routeTemplate: "api/{controller}/{id}/{action}"
    );

【讨论】:

    【解决方案2】:

    您要求的是 n 深度子资源,唯一真正解决此问题的是 Web API v2 中提供的属性路由。在它发布之前(我相信很快就会发布),您可以使用类似 RPC 的方法:

    routes.MapHttpRoute("RPC", "rpc/{controller}/{id}/{action}");
    

    您需要将其注册为第一个 HTTP 路由,并使用 'api' 以外的前缀,这样它就不会与实际的 api/ 路由冲突。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-22
      相关资源
      最近更新 更多