c# - 从 MS CRM 插件(沙盒)向 Azure 服务总线发送自定义消息

标签 c# azure dynamics-crm azureservicebus dynamics-crm-online

我知道我可以在 MS CRM 中注册一个新的“服务端点”并使用它向 Azure 服务总线发送消息,但这...并不是我真正想要的。上述方法最终发送一个序列化的RemoteExecutionContext

就我而言,我希望完全控制服务总线消息将包含的内容。这意味着序列化我自己的类。

我尝试过使用 WindowsAzure.ServiceBus block (并合并新的 DLL),但这仅适用于非沙盒设置(本地 CRM),但我也喜欢让我的解决方案能够在 CRM Online 中运行。当尝试在 CRM Online 中使用相同的代码然后尝试创建 TopicClient 时,会引发错误:

System.Security.SecurityException: That assembly does not allow partially trusted callers

有什么办法可以解决上述问题吗?

最佳答案

这是一种无需额外类且无需使用 ILMerge 即可完成此操作的方法。我验证了此功能在 CRM 在线版本 9.1.0.646 (Dynamics 365 Customer Engagement) 中有效

您的插件项目将需要以下引用和 using 语句。

引用文献:System.Net、System.Net.Http 使用:System.Net、System.Net.Http、System.Security.Cryptography、System.Globalization

在此示例代码中,我构建了一个名为 json 的字符串变量,它是我要发布的 JSON 消息。然后以下代码将发送消息。

string asbUri = 
    "https://<azurenamespace>.servicebus.windows.net/<topicname>/messages";
TimeSpan ts = new TimeSpan(0, 0, 90);
string sasToken = GetSASToken("sb://<azurenamespace>.servicebus.windows.net", " 
    <nameofSASkey>", "<SASKeyValue>", ts);

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", sasToken);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, asbUri)
{
    Content = new StringContent(json, Encoding.UTF8, "application/json")
};
HttpResponseMessage response = client.SendAsync(request).Result;

private static string GetExpiry(TimeSpan ttl)
{
   TimeSpan expirySinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1) + ttl;
   return Convert.ToString((int)expirySinceEpoch.TotalSeconds);
}

public static string GetSASToken(string resourceUri, string keyName, string key, 
TimeSpan ttl)
{
   var expiry = GetExpiry(ttl);
   //string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
   //NOTE: UrlEncode is not supported in CRM, use System.Uri.EscapeDataString instead
   string stringToSign = Uri.EscapeDataString(resourceUri).ToLowerInvariant() + "\n" 
        + expiry;
        HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));

   var signature = 
   Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
   var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature 
       sr={0}&sig={1}&se={2}&skn={3}",
       Uri.EscapeDataString(resourceUri).ToLowerInvariant(), 
       Uri.EscapeDataString(signature), expiry, keyName);
   return sasToken;
}

关于c# - 从 MS CRM 插件(沙盒)向 Azure 服务总线发送自定义消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46013501/

相关文章:

javascript - 如何通过包含列、名称、日期、设备的网格行中的文件名来保存文件

c# - 获取数据库中表的最后一条记录?

c# - Azure Kubernetes .NET Core 应用程序到 Azure SQL 数据库间歇性错误 258

plugins - 客户关系管理 2011 : How to Update record in a Create Plugin?

c# - 如何使用 AutoMapper 为特定映射映射空值?

c# - 如何将 TreeView 序列化为 xml 并将 xml 反序列化回 TreeView?

azure - 如何修复 azure 机器人服务的 slack channel 上的验证 token 错误?

azure - 如何防止 Azure DevOps 将信息和警告视为管道中的错误?

dynamics-crm - 'where' 条件无效。实体成员正在调用无效的属性或方法。 LINQ 查询错误

javascript - CRM 2011 调用 getAttribute 失败