由于API中JSON数据大小写的(外部)要求(有些请求应该使用camelCasing,而另一些请求应该使用PascalCasing),所以我有一小部分应用程序的API被分割成两个控制器。
现在,我有一个url,我想用PascalCasing映射为GET,而camelCasing映射为PUT,因此我尝试了以下操作:
[PascalCasing] // custom attribute, part of our code
// We configure all controllers that *don't* have this to use
// camelCasing
public class PascalCasedController : ApiController
{
[HttpGet]
[Route("url/to/my/resource/{id}")]
public IHttpActionResult(int id)
{
return Ok(GetResource(id));
}
}
public class CamelCasedController : ApiController
{
[HttpPut]
[Route("url/to/my/resource/{id}")]
public IHttpActionResult(int id, Resource resource)
{
SaveResource(id, resource);
return Ok();
}
}GET请求如预期的那样工作,但是如果我尝试使用Fiddler实现PUT,我会得到以下错误消息:
找到与URL匹配的多个控制器类型。如果多个控制器上的属性路由与请求的URL匹配,则可能发生这种情况。 请求找到了以下匹配的控制器类型: MyProject.PascalCaseController MyProject.CamelCaseController
我意识到这可能是因为WebAPI首先将路由映射到控制器,然后再映射到操作,但是如果考虑HTTP方法,这里就没有任何歧义。我是否可以告诉WebAPI如何做到这一点,而不必在同一个控制器中使用这些方法?
发布于 2017-06-08 22:00:02
@Tomas -在"System.Web.Http.Dispatcher.IHttpControllerSelector“程序集中公开了一个接口System.Web.Http。您可以使用该接口并创建自己的HttpControllerSelector。然后,您可以在DefaultControllerSelector期间用HttpConfiguration中的自定义控制器选择器替换AreaRegistration。
httpConfig.Services.Replace(typeof(IHttpControllerSelector),新CustomControllerSelector(services.GetHttpControllerSelector()));
在这个自定义控制器选择器中,您可以编写自己的SelectController() IHttpControllerSelector方法的实现,在该方法中可以调用IHttpControllerSelector的GetControllerMapping()方法。这将给出所有注册的控制器的列表。对于每个控制器,您可以检查DeclaredMethods,检查每个DeclaredMethods的CustomAttributes。在您的例子中,要么是HttpGetAttribute,要么是HttpPutAttribute。
检查传入HttpRequestMessage的方法类型(GET/PUT),并将其与CustomAttributes值进行比较。如果您找到了传入请求URL和相应的Http谓词组合的匹配,那么您将获取该HttpControllerDiscriptor并从SelectController()方法中返回它。
这将允许您在两个不同的控制器中具有不同方法的相同URL。
https://stackoverflow.com/questions/28319143
复制相似问题