2010-10-28 12 views
1

Nous avons du code qui a parfois vidé certaines clés du cache ASP.NET afin de nous assurer que nous obtenons des données à jour de notre système Dynamics CRM. Il semble fonctionner très bien la plupart du temps, mais nous recevons des exceptions intermittentes sur les rechargements de page que je soupçonne être lié à ce vidage forcé du cache.ASP.NET UnauthorizedAccessException lors de l'accès à l'élément à partir du cache

Voici l'erreur dans le UnauthorizedAccessException:

Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-129326029589946795:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query=953227368' is denied. 

Dans le cas où il est utile, voici comment je Flushing les éléments du cache:

private void Flush() 
    { 
     IDictionaryEnumerator cacheEnum = this.HttpContext.Cache.GetEnumerator(); 
     while (cacheEnum.MoveNext()) 
     { 
      var key = cacheEnum.Key.ToString(); 

      if (key.StartsWith("Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query")) 
       System.Web.HttpContext.Current.Cache.Remove(key); 
     } 
    } 

Mes questions:

  • Existe-t-il un niveau d'autorisation requis pour accéder ou supprimer des éléments de cache? J'ai googlé ceci mais n'ai rien trouvé de spécifique (même dans MSDN).
  • Avez-vous déjà vu cette erreur? Comment as-tu résolu ça?

MISE À JOUR: voici la pile de données.

Stacktrace: 
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(Object userData) 
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity) 
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Lock(String key, Int32 millisecondsTimeout, Action`1 action) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Int32 millisecondsTimeout, Func`2 loadFromCache, Func`2 loadFromService) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Func`2 loadFromCache, Func`2 loadFromService, Action`2 addToCache) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.InnerExecute[TRequest,TResponse,TResult](TRequest request, Func`2 execute, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute[T](MetadataServiceRequest request, Func`5 execute, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute[T](MetadataServiceRequest request, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute(Object request) 
at Microsoft.Xrm.Client.Services.IOrganizationServiceExtensions.RetrieveAllEntities(IOrganizationService service, MetadataItems metadataItems, Boolean retrieveAsIfPublished) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.GetId(DynamicEntity entity) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__48.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__41.MoveNext() 
at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__2b.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.<GetDependencies>d__13.MoveNext() 
at System.Linq.Enumerable.<DistinctIterator>d__81`1.MoveNext() 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.GetCachePolicy(Object query, Object result) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.Insert(String key, Object query, Object result) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.<>c__DisplayClass5`1.<Get>b__4(String k) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.<>c__DisplayClass2`1.<Get>b__0(Mutex _) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Lock(String key, Int32 millisecondsTimeout, Action`1 action) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Int32 millisecondsTimeout, Func`2 loadFromCache, Func`2 loadFromService) 
at Microsoft.Xrm.Client.Threading.MutexExtensions.Get[T](String key, Func`2 loadFromCache, Func`2 loadFromService, Action`2 addToCache) 
at Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider.InnerExecute[TRequest,TResponse,TResult](TRequest request, Func`2 execute, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.Execute[T](Request request, Func`2 selector, String selectorCacheKey) 
at Microsoft.Xrm.Client.Services.CachedOrganizationService.RetrieveMultiple(QueryBase query) 
at Microsoft.Xrm.Client.Services.IOrganizationServiceExtensions.Using[T](Func`1 create, Func`2 action) 
at Microsoft.Xrm.Client.Linq.CrmQueryProvider.Execute[TElement](QueryExpression qe, LambdaExpression projection, Delegate postMethodCall, LambdaExpression filter, Type entityType) 
at Microsoft.Xrm.Client.Linq.CrmQueryProvider.Execute[TElement](Expression expression) 
at Microsoft.Xrm.Client.Linq.QueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
at System.Linq.Queryable.Single[TSource](IQueryable`1 source) 
at FrontOfficeApp.Controllers.BillingController.GetBillingInstitutions(Requisition req) 
at FrontOfficeApp.Controllers.BillingController.InstitutionalBillPartial(Int32 requisitionId) 
at lambda_method(Closure , ControllerBase , Object[]) 
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 
at System.Web.Mvc.Controller.ExecuteCore() 
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() 
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Message=Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-119328537521157948:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:Query=913126368' is denied. 
Data=System.Collections.ListDictionaryInternal 

MAJ2: Nous venons à la version mis à jour 4.0.13 du SDK afin de désactiver la mise en cache (en fait je ne pouvais le faire fonctionner en réglant la durée à 1 seconde, voir ci-dessous). Cela nous permet de contourner le problème du CRM ont besoin d'être vidées, mais nous obtenons toujours les erreurs de mise en cache dans notre environnement, mais ils ont l'air un peu différent maintenant:

Message=Access to the path 'appDomain=/LM/W3SVC/1/ROOT-1-129341239247458264:key=Microsoft.Xrm.Client.Services.InMemoryCrmCacheProvider:Crm:User=00000000-0000-0000-0000-000000000000,00000000-0000-0000-0000-000000000000:Query=923237368' is denied. 
Data=System.Collections.ListDictionaryInternal 

Pour ce qui est vaut, le contexte configuration que j'utilise est ci-dessous. J'ajoute une prime à cette question comme tentative de dernier recours.

<microsoft.xrm.client> 
    <contexts default="Crm"> 
     <add name="Crm" type="CRM.XrmDataContext" serviceName="Default" /> 
    </contexts> 
    <services default="Default"> 
     <add name="Default" cacheProviderName="Default" /> 
    </services> 
    <cache defaultProvider="Default"> 
     <providers> 
      <add name="Default" 
       type="Microsoft.Xrm.Client.Caching.InMemoryCacheProvider, Microsoft.Xrm.Client" duration="00:00:01" /> 
     </providers> 
    </cache> 
</microsoft.xrm.client> 

Répondre

2

Nous avons finalement trouvé la réponse à ce problème. Le problème était lié à l'usurpation d'identité (nous l'avions activé dans le web.config) et au fait que nous accédions à XRM en utilisant un singleton. Apparemment, lorsque plusieurs utilisateurs essayaient d'exécuter des requêtes CRM simultanées via notre logiciel, le singleton établissait la connexion à CRM dans leur contexte utilisateur. Apparemment, alors que cela se produit, le cache des résultats de la requête est "détenu" par ce contexte d'utilisateur. Lorsqu'un autre utilisateur tentait d'exécuter une requête en même temps, il recevait un code d'état 401. Le correctif a fini par être de l'usurpation d'identité et faire un refactoring mineur afin que nous n'en ayons plus besoin. J'imagine que nous aurions pu autoriser plusieurs instances CRM - bien que nous ne le fassions pas intentionnellement pour des raisons de performances. J'espère que cela aidera tous ceux qui pourraient voir ces erreurs funky.

0

Je ne peux pas imaginer que l'exception est en fait liée à la Cache.Remove appel.

Juste une supposition, mais est-il possible que l'exception est liée à la CacheItemRemovedCallback et non l'étape d'élimination réelle (pas sûr si le rappel est exécuté de manière synchrone sur le même fil)?

Pouvez-vous publier la trace de pile complète pour l'exception?

+0

Je viens d'ajouter la pile. – jslatts