You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:54:14