Dynamics CRM 365 v9.1(本地部署):如何用Web API+C#筛选有读权限的Lead记录?
Dynamics CRM 365 v9.1(本地部署):筛选当前用户可读的Lead记录
针对需求,以下是基于Web API和C#的实现方案,核心利用CRM的RetrievePrincipalAccess函数检查权限,再批量筛选符合条件的Lead ID。
1. 核心逻辑
通过Web API调用RetrievePrincipalAccess函数,传入Lead实体逻辑名和记录ID,获取当前用户对该记录的权限集合,判断是否包含Read权限;批量场景下可通过批量请求($batch)提升效率。
2. 初始化认证HttpClient(本地部署AD认证)
本地部署通常采用Active Directory认证,先配置带认证的HttpClient:
using System.Net.Http; using System.Net.Http.Headers; using System.Security; using Microsoft.IdentityModel.Clients.ActiveDirectory; public HttpClient GetAuthenticatedCrmClient(string crmApiUrl, string username, string password, string domain) { var client = new HttpClient { BaseAddress = new Uri(crmApiUrl), Timeout = new TimeSpan(0, 2, 0) }; // 设置Web API请求头 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0"); client.DefaultRequestHeaders.Add("OData-Version", "4.0"); // AD认证流程 var securePassword = new SecureString(); foreach (char c in password) securePassword.AppendChar(c); var credential = new UserPasswordCredential($"{domain}\\{username}", securePassword); var authContext = new AuthenticationContext($"https://login.microsoftonline.com/{domain}"); var authResult = authContext.AcquireTokenAsync(crmApiUrl, "你的应用注册ClientID", credential).Result; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); return client; }
注:替换你的应用注册ClientID为实际应用ID,crmApiUrl格式为https://你的CRM服务器地址/api/data/v9.1/
3. 检查单条Lead的读权限
编写方法判断单条Lead记录是否对当前用户可读:
using System.Net.Http; using System.Threading.Tasks; using System.Text.Json; public async Task<bool> HasLeadReadAccess(HttpClient client, Guid leadId) { try { // 构造RetrievePrincipalAccess请求URL var requestUrl = $"RetrievePrincipalAccess(Principal=@p,Target=@t)?@p={{'@odata.type':'#Microsoft.Dynamics.CRM.systemuser','systemuserid':'{client.DefaultRequestHeaders.GetValues("MSCRMCallerID").FirstOrDefault()}'}}&@t={{'@odata.type':'#Microsoft.Dynamics.CRM.lead','leadid':'{leadId}'}}"; var response = await client.GetAsync(requestUrl); if (response.IsSuccessStatusCode) { var accessData = await response.Content.ReadAsStringAsync(); var accessResponse = JsonSerializer.Deserialize<PrincipalAccessResult>(accessData); return accessResponse.AccessRights.HasFlag(AccessRights.ReadAccess); } return false; } catch { return false; } } // 权限结果解析类 public class PrincipalAccessResult { public AccessRights AccessRights { get; set; } } // CRM权限枚举 [Flags] public enum AccessRights { None = 0, ReadAccess = 1, WriteAccess = 2, DeleteAccess = 4, AppendAccess = 8, AppendToAccess = 16, CreateAccess = 32, ShareAccess = 64, AssignAccess = 128 }
注:若调用API的用户即为当前检查用户,可省略MSCRMCallerID参数,直接使用认证用户的权限判断。
4. 批量筛选可读Lead ID
方式1:遍历单条检查(适用于少量ID)
public async Task<List<Guid>> FilterAccessibleLeads(HttpClient client, Guid[] leadIds) { var accessibleIds = new List<Guid>(); foreach (var id in leadIds) { if (await HasLeadReadAccess(client, id)) { accessibleIds.Add(id); } } return accessibleIds; }
方式2:批量请求(适用于大量ID,提升效率)
利用Web API的$batch功能一次性发送多个检查请求:
using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using System.Text.Json; public async Task<List<Guid>> BatchFilterAccessibleLeads(HttpClient client, Guid[] leadIds) { var batchId = Guid.NewGuid().ToString(); var batchContent = new MultipartContent("mixed", $"batch_{batchId}"); // 构造批量请求的每个子请求 foreach (var leadId in leadIds) { var requestUrl = $"RetrievePrincipalAccess(Principal=@p,Target=@t)?@p={{'@odata.type':'#Microsoft.Dynamics.CRM.systemuser','systemuserid':'{client.DefaultRequestHeaders.GetValues("MSCRMCallerID").FirstOrDefault()}'}}&@t={{'@odata.type':'#Microsoft.Dynamics.CRM.lead','leadid':'{leadId}'}}"; var subRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl); subRequest.Headers.Add("Content-Type", "application/json"); subRequest.Headers.Add("OData-Version", "4.0"); subRequest.Headers.Add("OData-MaxVersion", "4.0"); var part = new HttpMessageContent(subRequest); part.Headers.Add("Content-ID", leadId.ToString()); batchContent.Add(part); } // 发送批量请求并解析结果 var response = await client.PostAsync("$batch", batchContent); var accessibleIds = new List<Guid>(); if (response.IsSuccessStatusCode) { var batchResponse = await response.Content.ReadAsMultipartAsync(); foreach (var responsePart in batchResponse.Contents) { var contentId = responsePart.Headers.GetValues("Content-ID").First(); var leadId = Guid.Parse(contentId); var partContent = await responsePart.ReadAsStringAsync(); var accessResult = JsonSerializer.Deserialize<PrincipalAccessResult>(partContent); if (accessResult?.AccessRights.HasFlag(AccessRights.ReadAccess) == true) { accessibleIds.Add(leadId); } } } return accessibleIds; }
内容的提问来源于stack exchange,提问作者Andrey Bushman
相关产品推荐
相关产品推荐

