我正在使用 MVC4 和 Autofac 开发一个 Web 应用程序。我有一个全局异常过滤器,我在其中注入了一个记录器服务,所以我在 App_Start 中初始化它,如下所示:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(DependencyResolver.Current.GetService<IExceptionFilter>());
}
这是过滤器的一般布局: public class ErrorHandlerAttribute : HandleErrorAttribute { private readonly ILoggerService logger;
public ErrorHandlerAttribute(ILoggerService logger)
{
this.logger = logger;
}
public override void OnException(ExceptionContext filterContext)
{
//dostuff
}
public void LogError(ExceptionContext context)
{
try
{
logger.Error(context.Exception.Message, context.Exception);
}
catch (Exception) { }
}
}
如果我不使用 Autofac,我会有这样的东西:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ErrorHandlerAttribute());
filters.Add(new ErrorHandlerAttribute
{
View = "UnauthorizedException",
ExceptionType = typeof(UnauthorizedAccessException)
});
filters.Add(new ErrorHandlerAttribute
{
View = "PageNotFound",
ExceptionType = typeof(NotImplementedException)
});
}
ErrorHandlerAttribute 是我的自定义异常过滤器,源自 MVC 的 HandleErrorAttribute。
我希望能够保留重定向到自定义错误页面的能力,同时使用 Autofac 的注入和单个过滤器(因为我构建了它,所以它可以处理任何异常)。不幸的是,尽管在网络和其他论坛上搜索可能的解决方案,但我似乎找不到任何方法来做到这一点。我尝试了很多配置更改、不同的注册、集合解析等。
我希望它的工作方式与此类似:
builder.RegisterType<ErrorHandlerAttribute>().As<IExceptionFilter>().InstancePerHttpRequest();
builder.RegisterType<ErrorHandlerAttribute>().As<IExceptionFilter>()
.WithProperties(new List<NamedParameter>() { new NamedParameter("ExceptionType", typeof(UnauthorizedAccessException)), new NamedParameter("View", "UnauthorizedAccess") })
.InstancePerHttpRequest();
builder.RegisterType<ErrorHandlerAttribute>().As<IExceptionFilter>()
.WithProperties(new List<NamedParameter>() { new NamedParameter("ExceptionType", typeof(NotImplementedException)), new NamedParameter("View", "UnderConstruction") })
.InstancePerHttpRequest();
builder.RegisterFilterProvider();
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
DependencyResolver.Current.GetServices<IExceptionFilter>().ForEach(f => filters.Add(f));
}
令人惊讶的是,这可以编译并运行,但所有 3 个 IExceptionFilter 实例都是正常的,默认为 ErrorHandlerAttribute(View="Error" 和 ExceptionType=typeof(object))。
我知道 Autofac 将服务的最后一次注册作为默认值,并且我尝试评论三个注册中的两个,以及使用 PreserveExistingDefaults,但我所有的异常过滤器仍然带有默认值。
我是否误解了 WithProperties 扩展方法,或者是否有另一种类似的方法来实现我想要的?
编辑 1:
感谢 Alex 的建议,我通过使用 NamedPropertyParameter 并切换语句的顺序来解决它:
builder.RegisterType<ErrorHandlerAttribute>().As<IExceptionFilter>()
.WithProperties(new List<NamedPropertyParameter> { new NamedPropertyParameter("ExceptionType", typeof(UnauthorizedAccessException)), new NamedPropertyParameter("View", "UnauthorizedAccess") })
.InstancePerHttpRequest();
builder.RegisterType<ErrorHandlerAttribute>().As<IExceptionFilter>()
.WithProperties(new List<NamedPropertyParameter> { new NamedPropertyParameter("ExceptionType", typeof(NotImplementedException)), new NamedPropertyParameter("View", "UnderConstruction") })
.InstancePerHttpRequest();
builder.RegisterType<ErrorHandlerAttribute>().As<IExceptionFilter>().InstancePerHttpRequest();