为什么这两种API方法会产生冲突

时间:2013-01-29 20:15:53

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

我们正在开发一个MVC4 API应用程序,遇到了一个我们没有解释的奇怪问题。

API控制器有两种方法:

    [AllowAnonymous]
    [AcceptVerbs("Post", "Get")]
    public ArtifactContent Post(string userName, string password, string id) ...

    [AllowAnonymous]
    [AcceptVerbs("Get")]
    public HttpResponseMessage Get(string userName, string password, string id, EnumType contentType) ...

虽然这两种方法显然有不同的方法签名,但我们收到以下错误消息:

  

{“消息”:“发生了错误。”,“ExceptionMessage”:“多个   找到与请求匹配的操作:   [XXX] .Models.ArtifactContent Post(System.String,System.String,   类型上的System.String)   [XXX] .API.ArtifactContentController \ r \ nSystem.Net.Http.HttpResponseMessage   类型上的Get(System.String,System.String,System.String,ArtifactContentTypes)   [XXX] .API.ArtifactContentController “ ”ExceptionType“: ”System.InvalidOperationException“, ”堆栈跟踪“:”   在   System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext   controllerContext)\ r \ n at   System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext   controllerContext)\ r \ n at   System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext   controllerContext,CancellationToken cancellationToken)\ r \ n at   System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage   请求,取消语音取消语言)\ r \ n at   System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage   请求,取消语音取消语句)“}

我们可以通过进行这两个更改中的一个来解决错误,但我真的想知道为什么 .NET在两个签名明确时抛出错误不同:

  1. Get方法
  2. 中删除AcceptVerbs Post属性
  3. 更改Get方法的签名以将Enum接受为整数

1 个答案:

答案 0 :(得分:4)

这是ASP.NET Web API中已知的行为/问题/错误。

简而言之,当尝试将传入的HTTP请求与控制器内的相关操作进行匹配时,操作选择器(IHttpActionSelector)将不会考虑Enums

原因是默认情况下,只从int中挑选原始类型(即stringRouteData等)以找到匹配的操作。 Enum不是其中之一,所以它被忽略了,因此,即使你的动作从编译器的角度看有不同的签名,在动作选择器的眼中它们是相同的。

您可以在此处跟踪潜在解决方案的进度 - http://aspnetwebstack.codeplex.com/workitem/312

就目前而言,正如您所说,最佳解决方法是将enum作为intstring传递(并转换为enum)。