ASP.NET Web API获取子列表(分层资源)
我有以下rest架构,我想使用ASP.NET Web Api实现:
http://mydomain/api/students http://mydomain/api/students/s123 http://mydomain/api/students/s123/classes http://mydomain/api/students/s123/classes/c456
我使用ApiController和以下两种方法使前两个链接正常工作:
public class StudentsController : ApiController { // GET api/students public IEnumerable GetStudents() { } // GET api/students/5 public IEnumerable GetStudent(string id) { } }
在同一个控制器中,(或者我需要一个名为ClassesController的不同控制器?),我如何实现最后两个链接? 另外,“类”部分的路由是什么样的(如果需要)?
这是我的WebApiConfig(我想保持动态,而不是硬编码到/ classes的路径,如果可能的话:
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // EDIT - I'm getting 404's when trying to use this context.Routes.MapHttpRoute( name: "JobsApi", routeTemplate: this.AreaName + "/Students/{id}/Classes/{classId}", defaults: new { classId = RouteParameter.Optional } );
编辑这是我新创建的ClassesController:
public class ClassesController : ApiController { // GET api/classes public IEnumerable Get(string id) { return null; } }
我在尝试访问此url时遇到404错误:
http://mydomain/api/students/s123/classes
通过这种良好的分层方法,您可以更多地关注内部路由。 有一个很好的示例应用程序采用分层资源结构: PingYourPackage 。 检查出。
注意:我有一篇关于此问题的博客文章解释了下面的问题,并为那些包含一些代码示例的人提供了解决方案。 您可以查看更多详细信息:
- ASP.NET Web API中的分层资源结构
让我通过设置示例场景简要解释一下这里的问题。 对于这些类型的情况,这可能不是理想的方法,但很好地解决了这些问题。 假设您的数据库中有以下两个附属公司,用于装运公司:
- 会员1(身份证号码:100)
- 会员2(身份证号码:101)
然后假设这些附属公司附加了一些货物:
- 会员1(关键:100)
- 发货1(钥匙:100)
- 装运2(钥匙:102)
- 装运4(钥匙:104)
- 会员2(重点:101)
- 装运3(钥匙:103)
- 装运5(钥匙:105)
最后,我们希望拥有以下资源结构:
GET api/affiliates/{key}/shipments GET api/affiliates/{key}/shipments/{shipmentKey} POST api/affiliates/{key}/shipments PUT api/affiliates/{key}/shipments/{shipmentKey} DELETE api/affiliates/{key}/shipments/{shipmentKey}
路由问题
@Ali已经解释过了,但我在这里采用了不同的方法。 假设我们正在针对/api/affiliates/105/shipments/102
发送GET请求。 请注意,此处的会员密钥是105,不存在。 所以,我们希望尽快终止请求。 我们可以使用per-route消息处理程序来实现这一点。
授权问题
如果您具有某种类型的身份validation,您可能希望确保(在我们的场景中)经过身份validation的用户和请求的联盟资源相关。 例如,假设Affiliate1在Affiliate角色下进行身份validation,并且您已注册AuthorizeAttribute
以检查“Affiliate”角色授权。 在这种情况下,您将失败,因为这意味着Affiliate1可以访问以下资源: /api/affiliates/101/shipments
属于Affiliate2的/api/affiliates/101/shipments
。 我们可以使用自定义AuthorizeAttribute
消除此问题。
所有权问题
现在,以下URI应该为我提供正确的数据:
GET / api / affiliates / 100 /货运/ 102
但是,以下URI会发生什么:
GET / api / affiliates / 100 /货运/ 103
这应该为您提供“404 Not Found”HTTP响应,因为其ID为100的 联盟会员不拥有ID为103的货件 。
ASP.NET中的路由可以表达这些更复杂的规则,但需要明确设置。 例如,在这种情况下,您必须定义2个路由:
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/students/{studentId}/{controller}/{classId}", defaults: new { classId = RouteParameter.Optional } );
你会有一个控制器:
public class ClassesController { public TheClass Get(int studentId, int classId) { .... } }
这可能不是理想的,但主要的选择。
我正在进行分层路由,由于Web API中的实现问题,这是不可能的,但是这个问题现在已经修复,所以我可能会再次开始研究它。