2017-10-11 58 views
1

我使用Unity与我的WebApi项目,并使用配置文件注册类型。我已经注入依赖到控制器构造函数,它一直以精美的工作...直到我忘了类型映射并收到以下错误:ResolutionFailedException作为成功返回

An error occurred when trying to create a controller of type 'FooController'. Make sure that the controller has a parameterless public constructor.

的问题是不是我接收到错误。我可以轻松地添加映射来解决它。问题在于内部机制与客户端共享,客户端收到的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> 
+0

你能把它陷入Global'Application_Error()'吗? – Jasen

+0

不,我不是。看起来错误正在被某些东西捕获,然后打包成一个HTTP 200响应,并在主体中包含错误的XML表示。我不知道那是什么“东西”。 – KrimblKrum

回答

0

我在这里找到了答案:

  • 全:catch all unhandled exceptions in ASP.NET Web Api

    实现我的首选解决方案,当我得知以下几点由于CustomErrors设置,只有可见的堆栈跟踪错误。我忘了我在本地运行一切,CustomErrors = RemoteOnly。

  • 如果我只想捕获异常并记录它们,请添加IExceptionLogger。这是我为满足当前需求而实施的解决方案。
  • 如果我想捕捉异常并处理响应,则替换为 IExceptionHandler。这是很好的知道。
  • 这两种解决方案都不能捕获所有异常。我仍然使用Application_Error来捕获未在我的ApiController方法中捕获的异常。