Closed KingR1 closed 10 years ago
it looks like you are using Unity. Did you register the Dependency Resolver for Unity? Do you have the code for that?
On 18 August 2014 15:37, KingR1 notifications@github.com wrote:
I install Strathweb.CacheOutput.WebApi2 using Package Manager Console. Try to run my WebAPI project - get error : "Attempt by security transparent method 'System.Web.Http.GlobalConfiguration.get_Configuration()' to access security critical type 'System.Web.Http.HttpConfiguration' failed."
So i made search for solution and stopped at this post http://www.dotnetspider.com/resources/45576-Attempt-by-security-transparent-method.aspx So i do following : Update-Package Microsoft.AspNet.WebApi -Pre.
Then i get problem with CacheOutput :
{"message":"An error has occurred.","exceptionMessage":"Resolution of the dependency failed, type = \"WebApi.OutputCache.Core.Cache.IApiOutputCache\", name = \"(none)\".\r\nException occurred while: while resolving.\r\nException is: InvalidOperationException - The type IApiOutputCache does not have an accessible constructor.\r\n-----------------------------------------------\r\nAt the time of the exception, the container was:\r\n\r\n Resolving WebApi.OutputCache.Core.Cache.IApiOutputCache,(none)\r\n","exceptionType":"Microsoft.Practices.Unity.ResolutionFailedException","stackTrace":" at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable1 resolverOverrides)\r\n at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable1 resolverOverrides)\r\n at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides)\r\n at Microsoft.Practices .Unity.UnityContainerExtensions.Resolve(IUnityContainer container, Type t, ResolverOverride[] overrides)\r\n at Microsoft.Practices.Unity.WebApi.UnityDependencyResolver.SharedDependencyScope.GetService(Type serviceType)\r\n at WebApi.OutputCache.V2.CacheOutputConfiguration.GetCacheOutputProvider(HttpRequestMessage request)\r\n at WebApi.OutputCache.V2.CacheOutputAttribute.EnsureCache(HttpConfiguration config, HttpRequestMessage req)\r\n at WebApi.OutputCache.V2.CacheOutputAttribute.OnActionExecuting(HttpActionContext actionContext)\r\n at WebApi.OutputCache.V2.CacheOutputAttribute.System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func1 continuation)\r\n at System.Web.Http.Tracing.Tracers.ActionFilterTracer.<>cDisplayClass3.b0()\r\n at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEndAsync TResult\r\n at System.Web.Http.Tracing.Tracers.ActionFilterTracer.System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func1 continuation)\r\n at System.Web.Http.Controllers.ActionFilterResult.<>cDisplayClassb.<>cDisplayClassd.
b9()\r\n at System.Web.Http.Controllers.ActionFilterResult. d 2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetRe sult()\r\n at System.Web.Http.Controllers.ExceptionFilterResult.d0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Web.Http.Controllers.ExceptionFilterResult.d0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n at System.Web.Http.Tracing.Tracers.HttpControllerTracer.d5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNoti fication(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n at System.Web.Http.Tracing.ITraceWriterExtensions.d181.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","innerException":{"message":"An error has occurred.","exceptionMessage":"The type IApiOutputCache does not have an accessible constructor.","exceptionType":"System.InvalidOperationException","stackTrace":" at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForNullExistingObject(IBuilderContext context)\r\n at lambda_method(Closure , IBuilderContext )\r\n at Microsoft.Pract ices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>cDisplayClass1.b0(IBuilderContext context)\r\n at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)\r\n at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)\r\n at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)\r\n at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable1 resolverOverrides)"}} Attribute, that i add to Web API method GET() is next : [CacheOutput(ClientTimeSpan = 50, ServerTimeSpan = 50)]
What can cause problem with CacheOutPut and how to resolve it?
— Reply to this email directly or view it on GitHub https://github.com/filipw/AspNetWebApi-OutputCache/issues/89.
Hi, Filip. Yes, I use Unity and yes, I register it.
looks like your Unity adapter is throwing an exception when it shouldn't. Here you can find a proper implementation of Unity resolver http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
The caching library will try to grab IApiOutputCache
using the following precedence:
IApiOutputCache
from HttpConfiguration.Properties
IApiOutputCache from DependencyResolver
, default to MemoryCache
DependencyResolver
throws an error, rather than return a null it will fail - but that is then resolver's fault, as it should always return null
If you can't change the behavior unity resolver, you can always register IApiOutputCache
in the HttpConfiguration
:
httpConfiguration.CacheOutputConfiguration().RegisterCacheOutputProvider(() => new MemoryCacheDefault());
If you read the Unity article, there is even a highlighted note there :)
If the GetService method cannot resolve a type, it should return null. If the GetServices method cannot resolve a type, it should return an empty collection object. Don't throw exceptions for unknown types.
which is what your Unity resolver seems to be doing now
If you can't change the behavior unity resolver, you can always register IApiOutputCache in the HttpConfiguration:
httpConfiguration.CacheOutputConfiguration().RegisterCacheOutputProvider(() => new MemoryCacheDefault());
This also doesn't help me after I tried to make some changes in implementation of Unity resolver (firstly i user [Dependency] attribute, now - constructors for repositories)
please provide a repro project, I can have a look then
If it's allright - please get prototype of my project from here https://drive.google.com/file/d/0B60DXolm0D0GUWxxZG9ZUl9IeDQ/edit?usp=sharing (Connection String is some fake, working link /api/v1/holidays )
the unity dependency resolver you are using is botched because it doesn't handle errors properly (!). Use the one from the article I linked to http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
It works I tested it.
Alternatively add the following two lines in your web api configuration (not 1 like I said before :)
config.CacheOutputConfiguration().RegisterCacheOutputProvider(() => new MemoryCacheDefault());
config.CacheOutputConfiguration().RegisterDefaultCacheKeyGeneratorProvider(() => new DefaultCacheKeyGenerator());
This also works, even without changing the Unity resolver.
and thanks for providing the repro project - it helped a lot
Filip, Thanks! Problem is resolved!!! :+1:
I install Strathweb.CacheOutput.WebApi2 using Package Manager Console. Try to run my WebAPI project - get error :
"Attempt by security transparent method 'System.Web.Http.GlobalConfiguration.get_Configuration()' to access security critical type 'System.Web.Http.HttpConfiguration' failed."
So i made search for solution and stopped at this post http://www.dotnetspider.com/resources/45576-Attempt-by-security-transparent-method.aspx So i do following :
Update-Package Microsoft.AspNet.WebApi -Pre.
Then i get problem with CacheOutput :
{"message":"An error has occurred.","exceptionMessage":"Resolution of the dependency failed, type = \"WebApi.OutputCache.Core.Cache.IApiOutputCache\", name = \"(none)\".\r\nException occurred while: while resolving.\r\nException is: InvalidOperationException - The type IApiOutputCache does not have an accessible constructor.\r\n-----------------------------------------------\r\nAt the time of the exception, the container was:\r\n\r\n Resolving WebApi.OutputCache.Core.Cache.IApiOutputCache,(none)\r\n","exceptionType":"Microsoft.Practices.Unity.ResolutionFailedException","stackTrace":" at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable
1 resolverOverrides)\r\n at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable1 resolverOverrides)\r\n at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides)\r\n at Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, Type t, ResolverOverride[] overrides)\r\n at Microsoft.Practices.Unity.WebApi.UnityDependencyResolver.SharedDependencyScope.GetService(Type serviceType)\r\n at WebApi.OutputCache.V2.CacheOutputConfiguration.GetCacheOutputProvider(HttpRequestMessage request)\r\n at WebApi.OutputCache.V2.CacheOutputAttribute.EnsureCache(HttpConfiguration config, HttpRequestMessage req)\r\n at WebApi.OutputCache.V2.CacheOutputAttribute.OnActionExecuting(HttpActionContext actionContext)\r\n at WebApi.OutputCache.V2.CacheOutputAttribute.System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func
1 continuation)\r\n at System.Web.Http.Tracing.Tracers.ActionFilterTracer.<>cDisplayClass3.1 beginTrace, Func
1 execute, Action2 endTrace, Action
1 errorTrace)\r\n at System.Web.Http.Tracing.Tracers.ActionFilterTracer.System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func1 continuation)\r\n at System.Web.Http.Controllers.ActionFilterResult.<>c__DisplayClassb.<>c__DisplayClassd.<InvokeActionWithActionFilters>b__9()\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()\r\n at System.Web.Http.Controllers.ExceptionFilterResult.1.GetResult()\r\n at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()\r\n at System.Web.Http.Tracing.ITraceWriterExtensions.1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.1 resolverOverrides)"}}
Attribute, that i add to Web API method
GET()
is next :[CacheOutput(ClientTimeSpan = 50, ServerTimeSpan = 50)]
What can cause problem with CacheOutPut and how to resolve it?