不能正确缓存Dynamics CRM Online对象缓存
作者:互联网
我有一个要求,我们需要一个插件来从外部系统检索会话ID并将其缓存一定时间.我在实体上使用一个字段来测试会话是否真正被缓存.当我几次刷新CRM表单时,从输出中看,同一密钥有四个版本(始终一致).我尝试清除缓存并再次进行测试,但结果仍然相同.
任何帮助表示赞赏,在此先感谢.
页面每次刷新时输出:
20170511_125342:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125358:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125410:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125342:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125437:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125358:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125358:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
20170511_125437:1:55a4f7e6-a1d7-e611-8100-c4346bc582c0
为此,我实现了以下代码:
public class SessionPlugin : IPlugin
{
public static readonly ObjectCache Cache = MemoryCache.Default;
private static readonly string _sessionField = "new_sessionid";
#endregion
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
try
{
if (context.MessageName.ToLower() != "retrieve" && context.Stage != 40)
return;
var userId = context.InitiatingUserId.ToString();
// Use the userid as key for the cache
var sessionId = CacheSessionId(userId, GetSessionId(userId));
sessionId = $"{sessionId}:{Cache.Select(kvp => kvp.Key == userId).ToList().Count}:{userId}";
// Assign session id to entity
var entity = (Entity)context.OutputParameters["BusinessEntity"];
if (entity.Contains(_sessionField))
entity[_sessionField] = sessionId;
else
entity.Attributes.Add(new KeyValuePair<string, object>(_sessionField, sessionId));
}
catch (Exception e)
{
throw new InvalidPluginExecutionException(e.Message);
}
}
private string CacheSessionId(string key, string sessionId)
{
// If value is in cache, return it
if (Cache.Contains(key))
return Cache.Get(key).ToString();
var cacheItemPolicy = new CacheItemPolicy()
{
AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
Priority = CacheItemPriority.Default
};
Cache.Add(key, sessionId, cacheItemPolicy);
return sessionId;
}
private string GetSessionId(string user)
{
// this will be replaced with the actual call to the external service for the session id
return DateTime.Now.ToString("yyyyMMdd_hhmmss");
}
}
解决方法:
Daryl在这里对此做了很大的解释:https://stackoverflow.com/a/35643860/7708157
基本上,每个CRM系统没有一个MemoryCache实例,您的代码仅证明每个插件都有多个应用程序域,因此,即使存储在此类插件中的静态变量也可以具有多个值,您不能依赖这些值. MSDN上没有任何文档可以解释sanboxing的工作原理(在这种情况下尤其是应用程序域),但是使用静态变量当然不是一个好主意.当然,如果您在线处理,则无法确定是否只有一个或多个前端服务器(这也将导致这种行为)
标签:dynamics-crm-2013,dynamics-crm-online,dynamics-crm,dynamics-crm-2011,c 来源: https://codeday.me/bug/20191111/2019487.html