ASP.NET的Web API让孩子列表(分层资源) [英] ASP.NET Web API get child list (hierarchical resources)

查看:98
本文介绍了ASP.NET的Web API让孩子列表(分层资源)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我想要使用ASP.NET Web API来实现以下其余的模式:

 的http:// MYDOMAIN / API /生
HTTP:// MYDOMAIN / API /生/ S123
HTTP:// MYDOMAIN / API /生/ S123 /班
HTTP:// MYDOMAIN / API /生/ S123 /班/ c456

我已经得到了前两个环节使用ApiController正常工作,以下两种方法:

 公共类StudentsController:ApiController {
  //获取API /生
  公共IEnumerable的<的Student GT; GetStudents(){
  }  //获取API /生/ 5
  公共IEnumerable的<的Student GT; GetStudent(字符串ID){
  }
}

在此同一控制人(或做我需要一个叫做ClassesController?不同的控制器),我将如何实现的最后两个环节?此外,什么会为类部分的路由的样子(如有必要)?

下面是我的WebApiConfig(我想这让动态的,而不是硬编码的路线/类可能的话:

  config.Routes.MapHttpRoute(
  名称:DefaultApi
  routeTemplate:API / {}控制器/(编号),
  默认:新{ID = RouteParameter.Optional}
);//编辑 - 我得到404的尝试使用此当
context.Routes.MapHttpRoute(
  名称:JobsApi
  routeTemplate:this.AreaName +/学生/ {ID} /班/ {}的classId
  默认:新{=的classId} RouteParameter.Optional
);

编辑
这里是我的新创建ClassesController:

 公共类ClassesController:ApiController {
  //获取API /班
  公共IEnumerable的< theClass描述>获取(字符串ID){
      返回null;
  }
}

我试图去这个网址时,得到404错误:

 的http:// MYDOMAIN / API /生/ S123 /班


解决方案

通过这个漂亮的分层方法,你有更多的关注,在内部路由。这里是采用分层资源结构的好示例应用程序: PingYourPackage 。检查出来。


  

注意:我有一个博客帖子这个问题这也解释了以下关注,并给予那些有几个code样品的解决方案。您可以
  检查出来的更多详细信息:


  
  

让我设立了一个示例场景在这里解释的关注简要介绍。这可能不是为这些类型的情况下,所需的办法,但勾画出的关注非常好。比方说,你有你的数据库中以下两家关联的发货公司:


  • Affiliate1(ID:100)

  • Affiliate2(ID:101)

和再假设这些分支机构有连接到他们的一些出货量:


  • Affiliate1(注释:100)

    • Shipment1(注释:100)

    • Shipment2(注释:102)

    • Shipment4(注释:104)


  • Affiliate2(注释:101)

    • Shipment3(注释:103)

    • Shipment5(注释:105​​)


最后,我们希望有以下资源结构:

 获取API /分支机构/ {}键/出货
GET API /分支机构/ {}键/发货/ {} shipmentKey
POST API /分支机构/ {}键/出货
PUT API /分支机构/ {}键/发货/ {} shipmentKey
DELETE API /分支机构/ {}键/发货/ {} shipmentKey

路由担忧​​

@Ali已经解释过,但我在这里已经一个不同的方法。假设我们发送反对一个GET请求/ API /分支机构/ 105 /发货/ 102 。注意,联属键105此处不存在。因此,我们要在这里尽快终止该请求。我们可以用每个路由消息处理程序实现这一目标。

授权担忧

如果你有一些类型的身份验证的地方,你会希望确保(在这里我们的场景)的身份验证的用户和请求子公司的资源有关。例如,假设 Affiliate1 是在加盟作用验证和你有 AuthorizeAttribute 注册检查加盟角色授权。在这种情况下,你就会失败,因为这意味着 Affiliate1 可以得到以下资源: / API /分支机构/ 101 /发货属于到Affiliate2。我们可以解决这个问题,一个自定义的 AuthorizeAttribute

所有权的担忧

现在,下面的URI应该得到我正确的数据:


  

GET / API /分支机构/ 100 /发货/ 102


不过,会发生什么了以下网址:


  

GET / API /分支机构/ 100 /发货/ 103


这应该让你404未找​​到HTTP响应,因为的会员,其ID为 100 不拥有在装运 id为 103

I have the following rest schema that I'd like to implement using the 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

I've got the first two links working properly using the ApiController and the following two methods:

public class StudentsController : ApiController {
  // GET api/students
  public IEnumerable<Student> GetStudents() {  
  }

  // GET api/students/5
  public IEnumerable<Student> GetStudent(string id) {  
  }
}

In this same controller, (or do I need a different controller called ClassesController?), how would I implement the last two links? Also, what would the routing for the 'classes' part look like (if necessary)?

Here's my WebApiConfig (which I'd like to keep as dynamic, rather than hard-coding the route to the /classes if possible:

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 }
);   

EDIT Here's my newly created ClassesController:

public class ClassesController : ApiController {
  // GET api/classes
  public IEnumerable<TheClass> Get(string id) {    
      return null;
  }
}

I'm getting 404 Errors when attempting to go to this URL:

http://mydomain/api/students/s123/classes

解决方案

With this nice hierarchical approach, you have more concerns that routing internally. There is a good sample application which adopts the hierarchical resource structure: PingYourPackage. Check that out.

Note: I have a blog post about this issue which explains the below concerns and gives solutions to those with a few code samples. You can check it out for more details:

Let me explain the concerns here briefly by setting up a sample scenario. This may not be the desired approach for these type of situations but lays out the concerns very well. Let's say you have the below two affiliates inside your database for a shipment company:

  • Affiliate1 (Id: 100)
  • Affiliate2 (Id: 101)

And then assume that these affiliates has some shipments attached to them:

  • Affiliate1 (Key: 100)
    • Shipment1 (Key: 100)
    • Shipment2 (Key: 102)
    • Shipment4 (Key: 104)
  • Affiliate2 (Key: 101)
    • Shipment3 (Key: 103)
    • Shipment5 (Key: 105)

Finally, we want to have the following resource structure:

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}

Routing Concerns

@Ali already explained it but I've a different approach here. Assume that we are sending a GET request against /api/affiliates/105/shipments/102. Notice that the affiliate key is 105 here which doesn't exist. So, we would want to terminate the request here ASAP. We can achieve this with a per-route message handler.

Authorization Concerns

If you have some type of authentication in place, you would want to make sure (in our scenario here) that the authenticated user and the requested affiliate resource is related. For example, assume that Affiliate1 is authenticated under the Affiliate role and you have the AuthorizeAttribute registered to check the "Affiliate" role authorization. In this case, you will fail miserably because this means that Affiliate1 can get to the following resource: /api/affiliates/101/shipments which belongs to Affiliate2. We can eliminate this problem with a custom AuthorizeAttribute.

Ownership Concerns

Now, the following URI should get me the correct data:

GET /api/affiliates/100/shipments/102

However, what would happen for the below URI:

GET /api/affiliates/100/shipments/103

This should get you "404 Not Found" HTTP response because affiliate whose Id is 100 doesn't own the shipment whose id is 103.

这篇关于ASP.NET的Web API让孩子列表(分层资源)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆