【问题标题】:ASP.NET Web API 2 and Ninject - Ambiguous match foundASP.NET Web API 2 和 Ninject - 发现不明确的匹配
【发布时间】:2015-01-07 12:32:07
【问题描述】:

我将我的项目升级到 MVC5 和 Web API 2,现在我的 ASP.NET Web API 的 Ninject 过滤器绑定收到以下错误。我安装了 Ninject.Web.WebApi-RC 包。有关如何解决此问题的任何解决方案?

kernel.BindHttpFilter<ApiValidationFilter>(FilterScope.Action)
    .WhenControllerHas<ApiValidationAttribute>();

kernel.BindHttpFilter<HttpHeaderFilter>(FilterScope.Controller)
    .WhenControllerHas<HttpHeaderAttribute>()
    .WithConstructorArgumentFromControllerAttribute<HttpHeaderAttribute>("name", q => q.Name)
    .WithConstructorArgumentFromControllerAttribute<HttpHeaderAttribute>("value", q => q.Value);

源代码错误:

public static IEnumerable<object> GetCustomAttributes(this HttpControllerDescriptor actionDescriptor, Type type)
{
    return ((IEnumerable)typeof(HttpControllerDescriptor)
        .GetMethod("GetCustomAttributes").MakeGenericMethod(type)
        .Invoke(actionDescriptor, new object[0])).Cast<object>();
}

错误

<Response>
<Message>An error has occurred.</Message>
<ExceptionMessage>Ambiguous match found.</ExceptionMessage>
<ExceptionType>System.Reflection.AmbiguousMatchException</ExceptionType>
<StackTrace>
at System.RuntimeType.GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers) at System.Type.GetMethod(String name) at Ninject.Web.WebApi.FilterBindingSyntax.HttpActionDescriptorExtensionMethods.GetCustomAttributes(HttpControllerDescriptor actionDescriptor, Type type) in d:\Projects\Ninject.Web.WebApi\src\Ninject.Web.WebApi\FilterBindingSyntax\HttpActionDescriptorExtensionMethods.cs:line 54 at Ninject.Web.WebApi.FilterBindingSyntax.FilterFilterBindingBuilder`1.<>c__DisplayClass9.<WhenControllerHas>b__8(HttpConfiguration controllerContext, HttpActionDescriptor actionDescriptor) in d:\Projects\Ninject.Web.WebApi\src\Ninject.Web.WebApi\FilterBindingSyntax\FilterFilterBindingBuilder.cs:line 166 at Ninject.Web.WebApi.FilterBindingSyntax.FilterFilterBindingBuilder`1.<>c__DisplayClass2.<When>b__0(IRequest ctx) in d:\Projects\Ninject.Web.WebApi\src\Ninject.Web.WebApi\FilterBindingSyntax\FilterFilterBindingBuilder.cs:line 126 at Ninject.Planning.Bindings.BindingConfiguration.Matches(IRequest request) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Bindings\BindingConfiguration.cs:line 129 at Ninject.Planning.Bindings.Binding.Matches(IRequest request) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Bindings\Binding.cs:line 237 at Ninject.KernelBase.<>c__DisplayClass1c.<SatifiesRequest>b__1b(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 455 at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate) at Ninject.KernelBase.CanResolve(IRequest request) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 314 at Ninject.KernelBase.Resolve(IRequest request) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 345 at Ninject.ResolutionExtensions.GetResolutionIterator(IResolutionRoot root, Type service, Func`2 constraint, IEnumerable`1 parameters, Boolean isOptional, Boolean isUnique) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 263 at Ninject.ResolutionExtensions.GetAll[T](IResolutionRoot root, IParameter[] parameters) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 113 at Ninject.Web.WebApi.Filter.NinjectFilterProvider.GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor) in d:\Projects\Ninject.Web.WebApi\src\Ninject.Web.WebApi\Filter\NinjectFilterProvider.cs:line 57 at System.Web.Http.Controllers.HttpActionDescriptor.<InitializeFilterPipeline>b__0(IFilterProvider fp) at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext() at System.Linq.Buffer`1..ctor(IEnumerable`1 source) at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext() at System.Linq.Buffer`1..ctor(IEnumerable`1 source) at System.Linq.Enumerable.<ReverseIterator>d__a0`1.MoveNext() at System.Web.Http.Controllers.HttpActionDescriptor.<RemoveDuplicates>d__3.MoveNext() at System.Linq.Buffer`1..ctor(IEnumerable`1 source) at System.Linq.Enumerable.<ReverseIterator>d__a0`1.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at System.Web.Http.Controllers.HttpActionDescriptor.InitializeFilterPipeline() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at System.Lazy`1.get_Value() at System.Web.Http.Controllers.HttpActionDescriptor.GetFilterPipeline() at System.Web.Http.Controllers.HttpActionDescriptor.GetFilterGrouping() at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()
</StackTrace>
</Response>

【问题讨论】:

    标签: c# asp.net-web-api ninject


    【解决方案1】:

    在 Web.API 2.0 中,HttpControllerDescriptorGetCustomAttributes 方法没有两个重载,因此 .GetMethod("GetCustomAttributes") 会引发此异常。

    所以这是 Ninject 中的一个错误,但已在 2013 年 10 月 25 日修复:Fixed FilterInjection for WebApi2

    所以你有三个一个选项:

    • wait 更新到最新版本的 Ninject.Web.WebApi-RC 包,其中包含当前的 bugix:Ninject.Web.WebApi 3.0.2-unstable-9018
    • 您从 GitHub 获取源代码并为自己构建。
    • 使用 When 代替 WhenControllerHas 帮助程序,您使用固定的 GetCustomAttributes 调用逻辑。

    【讨论】:

    • 我已经在项目中有源代码,所以我刚刚更新了代码,它似乎可以工作了。
    • 更新后的代码适用于操作,但仍会为控制器出错。
    • @Omar bugHttpActionDescriptorExtensionMethods.GetCustomAttributes 中,所以在新版本未发布之前,您需要重写 every method,它像 WhenControllerHasWhenActionMethodHas 一样使用它跨度>
    • 我无法让它运行您提供的代码。你有什么理由打电话给GetCustomAttribute,而不是我的回答?
    • 在您的代码中,您可以直接调用actionDescriptor.ControllerDescriptor.GetCustomAttributes,在我的回答中,我已经从 Ninject 源代码存储库中复制并修改了源代码。我不能告诉你为什么 Ninject 会这样称呼它。无论如何,一个新版本的 web.api 集成已经在 nuget 上发布:nuget.org/packages/Ninject.Web.WebApi/3.0.2-unstable-9018 所以这个版本应该永久解决这个问题。
    【解决方案2】:

    nemsev 的回答为我指明了正确的方向,但我最终不得不使用以下内容:

    kernel.BindHttpFilter<ApiValidationFilter>(FilterScope.Action)
        .When((controllerContext, actionDescriptor) => 
                actionDescriptor.ControllerDescriptor.GetCustomAttributes<ApiValidationAttribute>().Any());
    

    【讨论】:

      猜你喜欢
      • 2016-04-12
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多