ResolutionFailedException作为成功返回

时间:2017-10-11 18:49:48

标签: c# asp.net-web-api unity-container

我在我的WebApi项目中使用Unity,并使用配置文件注册类型。我已经将依赖项注入到控制器构造函数中并且它一直工作得很漂亮......直到我忘记了类型映射并收到以下错误:

  

尝试创建类型为' FooController'的控制器时发生错误。确保控制器具有无参数的公共构造函数。

问题不在于我收到了错误。我可以轻松添加映射来解决它。问题是内部与客户端共享,客户端收到的HTTP状态代码为200。

我读了一篇类似的文章(Unity wraps exception to the ResolutionFailedException. How to avoid?),但这些答案没有帮助;说没有解决方案或看似主题。我很难接受没有解决方案,所以我想我可能会重新解释这个问题,希望能得到更好的答案。

如何捕获/拦截ResolutionFailedException以便返回Http Error 500?是否有我可以听的事件或者我可以用某种方式包装的课程?例如,我可以包装DefaultHttpControllerActivator并使用我的包装器来捕获异常并将其作为HTTP 500错误返回吗?我希望根据CustomErrors配置设置从客户端过滤HTTP 500。此外,我可以将错误记录到我的日志文件中,而不是将详细信息返回给客户端。

以下是XML的错误示例:

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
An error occurred when trying to create a controller of type 'FooController'. Make sure that the controller has a parameterless public constructor.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) 
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Resolution of the dependency failed, type = "MyWebApi.API.Controllers.FooController", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, MyWebApi.DataProvider.Interfaces.IFooProvider, is an interface and cannot be constructed. Are you missing a type mapping? ----------------------------------------------- 
At the time of the exception, the container was: Resolving MyWebApi.API.Controllers.FooController,(none) Resolving parameter "FooProvider" of constructor MyWebApi.API.Controllers.FooController(MyWebApi.DataProvider.Interfaces.IFooProvider FooProvider) Resolving MyWebApi.DataProvider.Interfaces.IFooProvider,(none)
</ExceptionMessage>
<ExceptionType>
Microsoft.Practices.Unity.ResolutionFailedException
</ExceptionType>
<StackTrace>
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) 
at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) 
at Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, Type t, ResolverOverride[] overrides) 
at Microsoft.Practices.Unity.WebApi.UnityDependencyResolver.SharedDependencyScope.GetService(Type serviceType) 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
</StackTrace>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The current type, MyWebApi.DataProvider.Interfaces.IFooProvider, is an interface and cannot be constructed. Are you missing a type mapping?
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context) 
at lambda_method(Closure , IBuilderContext ) 
at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) 
at Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) 
at lambda_method(Closure , IBuilderContext ) 
at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) 
at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) 
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
</StackTrace>
</InnerException>
</InnerException>
</Error>

1 个答案:

答案 0 :(得分:1)

我在这里找到答案:catch all unhandled exceptions in ASP.NET Web Api

在实施我的首选解决方案时,我学到了以下几点:

  • 只有CustomErrors设置才能看到带有堆栈跟踪的完整错误。我忘了我在本地运行所有东西而且CustomErrors = RemoteOnly。
  • 如果我只想捕获异常并记录它们,那么添加一个IExceptionLogger。这是我针对当前需求实施的解决方案。
  • 如果我想捕获异常并操纵响应,那么替换 IExceptionHandler。很高兴知道这一点。
  • 两种解决方案都不会捕获所有异常。我仍在使用Application_Error来捕获我的ApiController方法中没有捕获的异常。