网页API 2属性路由控制器选择 [英] Web API 2 Attribute Routing Controller Selection

查看:218
本文介绍了网页API 2属性路由控制器选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的Web API 2属性的路由在我的项目超过我的数据提供JSON接口。我对着控制器选用怪异的行为,尚未决定它是否是一个错误或功能:)
让我来形容我的做法。

I use Web API 2 Attribute Routing in my project to provide JSON interface over my data. I am facing weird behaviour of controller selection, not decided yet whether it's a bug or a feature :) Let me describe my approach.

我想以模拟属性路由帮助的OData语法(直接使用OData的被拒绝,由于设计原则)。例如,用id来获取实体= 5我使用HTTP GET请求的URI http://mydomain.com / API /实体(5)。我希望使用相同的URI与HTTP PUT动词更新实体。这是旅程开始了......

I would like to simulate OData syntax with help of attribute routing (direct OData usage has been refused due to design principles). For example, to get entity with id=5 I use HTTP GET request to URI http://mydomain.com/api/Entity(5) . I expect to use the same URI with HTTP PUT verb to update the entity. This is where the journey begins...

我想有获取实体单独的控制器( FirstController 在下面提供的示例),另一种用于修改实体( SecondController )。两个控制器处理相同的URI(如 http://mydomain.com/api/Entity(5)),唯一的区别是与URI使用HTTP动词 - 获取应 FirstController 处理,PUT应该由 SecondController 。但是URI由其中没有处理;而不是返回HTTP 404错误。
当我合并GET和PUT动作只有一个控制器(在 FirstController 注释掉),这两个动词正确处理。
我使用IIS防爆preSS和所有常规路线是残疾人,只读属性路由负责。

I would like to have separate controller for getting entities (FirstController in the example provided below) and another one for modifying entities (SecondController). Both controllers handles the same URI (e.g. http://mydomain.com/api/Entity(5)) the only difference is HTTP verb used with the URI - GET should be handled by FirstController, PUT should be handled by SecondController. But the URI is handled by none of them; instead HTTP 404 error is returned. When I "merge" GET and PUT actions to only one controller (commented out in FirstController), both verbs are handled correctly. I am using IIS Express and all conventional routes are disabled, only attribute routing is in charge.

它看起来像控制器选择过程中不使用HTTP动词工作。换句话说, HTTPGET HttpPut 属性只是限制使用的行动,但他们不作为控制器选择过程中的标准。我不是那么熟悉的MVC /网页API的基本面,所以让我问你我的大问题:

It looks like the controller selection process does not work with HTTP verb. In another words, HttpGet and HttpPut attributes just limit action usage but they do not serve as criteria during controller selection. I am not so familiar with MVC / Web API fundamentals, so let me ask you my big question:

与行为,在此之前描述的,故意的MVC /网页API 2或错误执行一个功能,能解决吗?

如果它被认为是一种功能,它prevents我遵循的设计原则。我可以合并控制器生活,但仍在考虑它作为一个不好的做法?
还是我缺少了我的思路的东西吗?

If it is considered as a feature, it prevents me to follow design principles. I can live with "merged" controllers but still considering it as a bad practice... Or am I missing something in my train of thought?

我的环境设置:


  • Windows 7中(使用Oracle的VirtualBox虚拟机)

  • 的Visual Studio 2013

  • .NET 4.5.1

  • 的Web API 2

下面是实施 FirstController 类:

public class FirstController : ApiController
{
  [HttpGet]
  [Route("api/Entity({id:int})")]
  public Output GetEntity(int id)
  {
    Output output = new Output() { Id = id, Name = "foo" };

    return output;
  }

  //[HttpPut]
  //[Route("api/Entity({id:int})")]
  //public Output UpdateEntity(int id, UpdateEntity command)
  //{
  //  Output output = new Output() { Id = id, Name = command.Name };

  //  return output;
  //}
}

下面是实施 SecondController 类:

public class SecondController : ApiController
{
  [HttpPut]
  [Route("api/Entity({id:int})")]
  public Output UpdateEntity(int id, UpdateEntity command)
  {
    Output output = new Output() { Id = id, Name = command.Name };

    return output;
  }
}

下面是实现一个控制台应用程序来测试所描述的行为:

The following is implementation of a console application to test the described behaviour:

class Program
{
  static void Main(string[] args)
  {
    // HTTP client initialization
    HttpClient httpClient = new HttpClient();
    httpClient.BaseAddress = new Uri("http://localhost:1567");
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // HTTP GET - FirstController.GetEntity
    HttpResponseMessage getEntityResponse = httpClient.GetAsync("/api/Entity(5)").Result;
    Output getOutput = getEntityResponse.Content.ReadAsAsync<Output>().Result;

    // HTTP PUT - SecondController.UpdateEntity
    UpdateEntity updateCommand = new UpdateEntity() { Name = "newEntityname" };
    HttpResponseMessage updateEntityResponse = httpClient.PutAsJsonAsync("/api/Entity(10)", updateCommand).Result;
    Output updateOutput = updateEntityResponse.Content.ReadAsAsync<Output>().Result;
  }
}

有关完成,以下使用的DTO:

For completion, the following are used DTOs:

public class UpdateEntity
{
  public string Name { get; set; }
}


public class Output
{
  public int Id { get; set; }
  public string Name { get; set; }
}

在此先感谢您的答复,

Thanks in advance for your responses,

扬Kacina

推荐答案

这个设计是故意的,因为我们认为这是一个错误的情况下,用户将有不同的控制器,可以在选择过程中引起歧义原路模板

This design was intentional as we thought it to be an error case where a user would be having same route template on different controllers which can cause ambiguity in the selection process.

此外,如果我们留着备用路由的属性,怎么会与常规路由这项工作?让我们想象一下,我们有2条航线,其中第一个是针对FirstController和第二个SecondController。现在,如果一个请求URL就像 API /实体(5),则Web API总是匹配的路由表,总是打FirstController一号路线,绝不会达到SecondController。请记住,一旦网页API的路由匹配它试图去,直到操作选择的过程,如果操作选择过程不会在动作导致被选中,然后一个错误响应发送到客户端。你可能是假设如果一个控制器不选择则Web API行动将其路由到该路由配置下一个。这是不正确。

Also if we keep aside attribute routing, how would this work with regular routing? Let's imagine we have 2 regular routes where first one is targeted for FirstController and the second to SecondController. Now if a request url is like api/Entity(5), then Web API would always match the 1st route in the route table which would always hit the FirstController and would never reach SecondController. Remember that once Web API matches a route it tries to go till the action selection process and if the action selection process doesn't result in an action being selected, then an error response is sent to the client. You probably are assuming that if an action is not selected in one controller then Web API would route it to the next one in the route configuration. This is incorrect.

路由探测只发生一次,如果它导致了比赛,那么接下来的步骤发生......这是控制器和动作选择。希望这有助于。

Route probing occurs only once and if it results in a match, then the next steps take place...that is controller and action selection. Hope this helps.

这篇关于网页API 2属性路由控制器选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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