加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – Autofac MVC 5 RegisterWebApiFilterProvider导

发布时间:2020-12-16 07:19:46 所属栏目:asp.Net 来源:网络整理
导读:我有一个简单的MVC应用程序,我正在尝试添加一个异常过滤器.为此,我遵循了我认为适用于Autofac.WebApi2 NuGet包的 Autofac WebAPI Integration documentation. 首先,我创建了异常过滤器: public class ErrorLoggingExceptionFilter : IAutofacExceptionFilte
我有一个简单的MVC应用程序,我正在尝试添加一个异常过滤器.为此,我遵循了我认为适用于Autofac.WebApi2 NuGet包的 Autofac WebAPI Integration documentation.

首先,我创建了异常过滤器:

public class ErrorLoggingExceptionFilter : IAutofacExceptionFilter
{
    public void OnException(HttpActionExecutedContext context)
    {
        // do something 
    }
}

然后我将AutofacControllerConfiguration属性添加到我想要应用异常过滤器的API控制器基类:

[AutofacControllerConfiguration]
public class ApiControllerBase : ApiController  {}

然后我用Autofac注册了异常过滤器:

builder.RegisterType<ErrorLoggingExceptionFilter>()
    .AsWebApiExceptionFilterFor<ApiControllerBase>()
    .InstancePerApiRequest();

此时应用程序仍然正常运行,但异常过滤器没有运行,因此我注册了autofac的过滤器提供程序:

builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

一旦添加,我开始得到500’s,出现以下错误:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Autofac.Features.Metadata.Meta1[System.Web.Http.Filters.IOverrideFilter]' can be invoked with the available services and parameters: Cannot resolve parameter 'System.Web.Http.Filters.IOverrideFilter value' of constructor 'Void .ctor(System.Web.Http.Filters.IOverrideFilter,System.Collections.Generic.IDictionary2[System.String,System.Object])'.

我没有在这个项目中使用任何元数据,也不知道有关IOverrideFilter的任何信息.

我错过了什么阻止我的异常过滤器工作?

更新&对评论的回应

该项目使用ASP.NET MVC 5.1,使用以下Autofac和WebApi NuGet版本:

<package id="Autofac" version="3.2.0" targetFramework="net45" />
<package id="Autofac.Mvc5" version="3.2.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.1.1" targetFramework="net45" />

我看到与Autofac 3.3相同的结果.

事实证明我可以通过只调用RegisterWebApiFilterProvider方法来重现它,所以虽然我整理了一个完整的样本,但我并没有打扰包括上面的异常过滤器.可以在我的Google Drive上找到可用于重现它的示例项目.

作为参考,这是完整的堆栈跟踪:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Autofac.Features.Metadata.Meta`1[System.Web.Http.Filters.IOverrideFilter]' can be invoked with the available services and parameters: Cannot resolve parameter 'System.Web.Http.Filters.IOverrideFilter value' of constructor 'Void .ctor(System.Web.Http.Filters.IOverrideFilter,System.Collections.Generic.IDictionary`2[System.String,System.Object])'.
at
Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context,IEnumerable`1 parameters) at
Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters) at
Autofac.Core.Resolving.InstanceLookup.Execute() at
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope,IComponentRegistration registration,IEnumerable`1 parameters) at
System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at
System.Linq.Buffer`1..ctor(IEnumerable`1 source) at
System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) at
Autofac.Features.Collections.CollectionRegistrationSource.<>c__DisplayClass4.<RegistrationsFor>b__0(IComponentContext c,IEnumerable`1 p) at
Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context,IEnumerable`1 parameters) at
Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration,IEnumerable`1 parameters) at
Autofac.ResolutionExtensions.ResolveService(IComponentContext context,Service service,IEnumerable`1 parameters) at
Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context,IEnumerable`1 parameters) at
Autofac.Integration.WebApi.AutofacWebApiFilterProvider.ResolveControllerScopedOverrideFilter(FilterContext filterContext,String metadataKey) at
Autofac.Integration.WebApi.AutofacWebApiFilterProvider.GetFilters(HttpConfiguration configuration,HttpActionDescriptor actionDescriptor) 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.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()

解决方法

我会说这是 bug?或至少两个Autofac功能之间的意外干扰.

所以这就是发生的事情:

>因为您在示例中使用AnyConcreteTypeNotAlreadyRegisteredSource,Autofac会尝试注册并解析未在控制器中注册的所有类型
>调用builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration); Autofac尝试定位所有过滤器,并在其中注册的IOverrideFilters,调用Resolve< IEnumerable< Meta< IOverrideFilter>>>
>但是,如果没有注册IOverrideFilter,则Autofac会处理Meta< IOverrideFilter>因为无法解析所以AnyConcreteTypeNotAlreadyRegisteredSource kickc试图实例化Meta< IOverrideFilter>并抛出异常.

此问题有多种解决方法:

>只是不要使用AnyConcreteTypeNotAlreadyRegisteredSource,尽管这可能不是你想要做的.
>至少注册一个过滤器覆盖

builder.OverrideWebApiActionFilterFor<SomeController>();

所以容器将包含Meta< IOverrideFilter>因此AnyConcreteTypeNotAlreadyRegisteredSource不会针对此类型运行.再次,如果您没有要覆盖的过滤器,这不是一个好的解决方案.
>您可以告诉AnyConcreteTypeNotAlreadyRegisteredSource它应该解析哪些类型,这样您也可以告诉它不应该解析Meta< T>:

builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(
 t => !(t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Meta<>))));

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读