【问题标题】:Restful MVC Web Api InheritanceRestful MVC Web API 继承
【发布时间】:2012-07-05 11:56:31
【问题描述】:

我正在为自己构建一个 asp.net mvc 4 web api

我已经通过Microsoft videos,我认为他们很好。使用了 Http 动词。资源是名词,存储库等等。

但有一件事让我很烦恼

我的印象是这个GET http://www.myurl.com/api/sellers/{id}/products 是宁静的,而GET http://www.myurl.com/api/products?$filter = sellerID eq {id} 不是。

在我所读到的关于新 Web api 的内容中,我看到的只是 前者 后者。

是否有对 latter 前者的原生支持?如果没有,有没有办法不路由所有内容


编辑-
我正在寻找允许GET http://www.myurl.com/api/sellers/{id}/productsGET http://www.myurl.com/api/products 等的东西


更新:
这个问题有一段时间没有意义,我已经解决了这个问题,但这就是为什么第一个答案没有被标记为正确的原因。


更新:
在与 MilkyWayJoe 聊天后,我们谈到将 /Seller/2/Products 转换为 /Products?$filter = sellerID eq 2。有没有人知道如何才能做到这一点?

【问题讨论】:

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


    【解决方案1】:

    网址http://www.myurl.com/api/products?$filter= sellerID eq {id} 使用OData 过滤器,当您的控制器将集合返回为IQuerable 时,它在Web API 中即用即用。 VS 2012 中的默认当前设置为IEnumerable,不支持OData。

    您可以找到有关此herehere 的更多信息。

    【讨论】:

    • 对不起,当我指的是前者时,我不小心说了后者。我已经编辑并修复了这个问题。
    • @MrJD 看看 Programming Hero 的回复。它基本上是一种不同的路由模式,类似于 rails 的路由。也检查this,你会看到还有其他类似的路线,例如GET /people/1/edit 本质上是一个 GET
    • 我只是在 get 之前明确定义一个动词。它不一定与问题有关。该方法需要我为每个端点路由每个嵌套情况。我想要一种抽象的方法。
    • 我不知道您如何注册路由以基于 FK 进行查询(可能是因为我缺乏 url 路由方面的经验)。我通常会为这些场景注册路线,同样,这是一个与 rails 和/或 sinatra 路线非常相似的约定(如果不完全相同的话),所以恕我直言,您必须注册这些其他路线。跨度>
    • 是否可以注册一个“嵌套”区域,例如“{nestedArea}/products”,然后以某种方式将其转换为 OData?或者以某种方式使用 iQuerable 结果?
    【解决方案2】:

    可能有嵌套资源(至少在 URL 构造中),但在 MVC 中没有大量支持;您必须自己完成大部分工作。

    首先,您需要创建一个路由来处理您的结构:

    url: "sellers/{sellerId}/products",
    defaults: new { controller = "sellers", action = "GetProducts" }
    

    然后,您需要在“卖家”控制器上创建 GetProducts 操作,此路由应将调用者定向到:

    [HttpGet]
    public IEnumerable<Product> GetProducts(int sellerId)
    {
        //TODO: Add query to return results.
    }
    

    sellerId 参数将通过路由传入,应该用于驱动您的查询。

    这种方法的主要缺点是自定义路由使得为资源之间的链接生成 URL 变得更加困难,并且当它们变得更加复杂时,它们可以开始匹配您没想到的 URL。

    【讨论】:

    • 我的问题是“没有路由一切”。这确实有效,但是我不想为单个端点创建 4 条深度嵌套路由。它只是效率不高。
    • 唉,正如我所说,MVC4 不自然地支持你正在尝试做的事情。您可以通过在路由中定义更多参数来使路由可重用,但最终,如果您希望将特定 URL 解析为特定操作和控制器,路由系统旨在解决此问题。
    • 我只是在寻找可变路由。阅读 MilkyWayJoe 答案的 cmets 的最后。我提到将路由参数转换为 OData 结构
    【解决方案3】:

    我正在寻找解决您同样问题的方法。我目前正在测试这个解决方案。

    首先,改变路线:

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

    然后,如果你想要一个SellersController,照常写它,但将所有动作命名为“索引”并使用符号来正确路由 http 动词。例如:

         [HttpGet]
         public List<Seller> Index()
         {}
    

    然后,在 SellersController 中,创建将它们命名为“内部”对象 (Products) 的操作。

         [HttpGet]
         public List<Product> Products(int id)
         {}
    
         [HttpGet]
         public Product Products(int id, int id2)
         {}
    

    这样就可以调用

         GET /api/sellers
         or GET /api/sellers/99/products
         or GET /api/sellers/99/products/2
    

    我实际上正在测试这种方法,所以任何反馈都将不胜感激!

    【讨论】:

    • 这很聪明。但是它并没有像我想要的那样扩展。例如。假设产品可以有评论,并且您想请求卖家 142 的所有评论。请求看起来像:/sellers/142/products/reviews。这是一个 3 级请求。可悲的是,您的示例似乎最多可以处理两个
    猜你喜欢
    • 1970-01-01
    • 2013-04-19
    • 2013-12-19
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 2014-09-11
    • 1970-01-01
    相关资源
    最近更新 更多