2017-10-11 109 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方法中捕獲的異常。