RetrievePrincipleAccess AccessRights 从 Web API 始终为空 - Dynamics CRM 2016

RetrievePrincipleAccess AccessRights always null from Web API - Dynamics CRM 2016

我无法检索对 CRM 中特定记录的访问权限。

我正在按照此处的建议使用 RetrievePrincipalAccess Web API 调用:

https://msdn.microsoft.com/en-us/library/mt683539.aspx

但是,AccessRights 字段始终为空。

无论用户是系统管理员还是任何安全角色,都会发生这种情况。

这是我的代码:

var crmTesting = {
tests: {
    getUserPrivilegesForRecord: function () {
        var recordId = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
        var userId = Xrm.Page.context.getUserId().replace('{', '').replace('}', '');
        console.log(recordId);
        console.log(userId);
        crmTesting.api.retrievePrincipalAccess(userId, 'accounts', recordId, function (r) {
            console.log(r);
        });
    }
},
api: {
    retrievePrincipalAccess: function (userId, entityPluralName, entityId, callback) {
        if (!this.context.loaded) {
            this.context.init();
        }
        var url = 'systemusers(' + userId 
            + ")/Microsoft.Dynamics.CRM.RetrievePrincipalAccess(Target=@tid)?@tid={'@odata.id':'" 
            + entityPluralName + '(' + entityId + ")'}";
        this.get(url, callback);
    },
    get: function (url, callback, error) {
        if (!this.context.loaded) {
            this.context.init();
        }
        var xhr = new XMLHttpRequest();
        xhr.open('GET', this.context.clientUrl + '/api/data/v8.1/' + url);
        xhr.setRequestHeader('Accept', 'application/json');
        xhr.setRequestHeader('Prefer', 'odata.include-annotation=OData.Community.Display.V1.FormattedValue');
        xhr.setRequestHeader('OData-MaxVersion', '4.0');
        xhr.setRequestHeader('OData-Version', '4.0');
        xhr.onload = function () {
            if (xhr.status == 200) {
                if (typeof callback != 'undefined') {
                    var result = JSON.parse(xhr.responseText);
                    callback(result);
                }
            }
            else if (xhr.status == 204) {
                if (typeof callback != 'undefined') {
                    callback();
                }
            }
            else {
                console.error(xhr.responseText);
                if (typeof error != 'undefined') {
                    error(xhr.responseText);
                }
                return;
            }
        };
        xhr.send();
    },
    post: function (url, data, callback, error) {
        if (!this.context.loaded) {
            this.context.init();
        }
        var xhr = new XMLHttpRequest();
        xhr.open('POST', this.context.clientUrl + '/api/data/v8.1/' + url);
        xhr.setRequestHeader('Accept', 'application/json');
        xhr.setRequestHeader('Context-Type', 'application/json; charset=utf-8');
        xhr.setRequestHeader('OData-MaxVersion', '4.0');
        xhr.setRequestHeader('OData-Version', '4.0');
        xhr.onload = function () {
            if (xhr.status == 200 || xhr.status == 204) {
                try {
                    var response = JSON.parse(xhr.responseText);
                    if (typeof callback != 'undefined') {
                        callback(response);
                    }
                }
                catch (e) {
                    console.log('Request successful. No response.');
                }
                return;
            }
            else {
                console.error(xhr.responseText);
                if (typeof error != 'undefined') {
                    error(xhr.responseText);
                }
            }
        };
        if (typeof data == 'string') {
            xhr.send(data);
        }
        else {
            xhr.send(JSON.stringify(data));
        }
    },
    context: {
        loaded: false,
        context: {},
        clientUrl: '',
        init: function () {
            this.context = this.getContext();
            this.clientUrl = this.context.getClientUrl();
            this.loaded = true;
        },
        getContext: function () {
            if (typeof GetGlobalContext != 'undefined') {
                return GetGlobalContext();
            }
            else if (typeof Xrm != 'undefined') {
                return Xrm.Page.context;
            }
            else {
                throw new Error('Context is not available.');
            }
        }
    }   
}
};

任何关于为什么会发生这种情况的帮助将不胜感激。

不确定这是 Microsoft 的错误还是我做错了什么所以想在这里验证它。

我的要求headers:

Accept:application/json
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Cookie:<cookie>
Host:<domainurl>
OData-MaxVersion:4.0
OData-Version:4.0
Pragma:no-cache
Prefer:odata.include-annotation=OData.Community.Display.V1.FormattedValue
Referer:<crmorgurl>/form/ClientApiWrapper.aspx?ver=1916985412
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36

我的回复headers:

Cache-Control:no-cache
Content-Encoding:gzip
Content-Length:169
Content-Type:application/json; odata.metadata=minimal
Date:Wed, 24 May 2017 10:03:51 GMT
Expires:-1
OData-Version:4.0
Pragma:no-cache
REQ_ID:e5b24ef1-4531-4492-a251-dc9e7f91875e
Server:Microsoft-IIS/8.5
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

查询字符串参数:

@tid:{'@odata.id':'accounts(C0988888-6EF4-E611-80FD-005056AC5406)'}

我尝试使用 DigitalFlow 的 Xrm-WebApi-Client 库并得到了同样的结果。

请求headers:

GET /<orgname>/api/data/v8.0/systemusers(F52C4FBB-E653-E611-80FB-005056AC5406)/Microsoft.Dynamics.CRM.RetrievePrincipalAccess(Target=@p1)?@p1={%22@odata.id%22:%22accounts(06918888-6EF4-E611-80FD-005056AC5406)%22} HTTP/1.1
Host: <crmdomain>
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
OData-Version: 4.0
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Content-Type: application/json; charset=utf-8
Accept: application/json
If-None-Match: null
OData-MaxVersion: 4.0
Referer: <crmorgurl>/form/ClientApiWrapper.aspx?ver=1916985412
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
Cookie: <cookie>

响应Headers:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Content-Encoding: gzip
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
REQ_ID: 6981cbe8-1f66-42af-8227-bcd855c90ec7
OData-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 31 May 2017 11:57:20 GMT
Content-Length: 170

我确认这是本地 Dynamics CRM 2016(在 8.1.1.1005 上测试)中的错误。

我最终创建了一个自定义工作流 activity 和一个操作。

自定义工作流程activity

创建并注册新的自定义工作流程activity

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using System;
using System.Activities;

namespace ****.WF.CheckRecordPermissions
{
    public class CheckRecordPermissions : CodeActivity
    {

        [Input("Entity logical name (if null use context)")]
        public InArgument<string> entityP { get; set; }

        [Input("Entity GUID (if null use context)")]
        public InArgument<string> guidP { get; set; }

        [Input("User to check (if null use context)")]
        [ReferenceTarget("systemuser")]
        public InArgument<EntityReference> userP { get; set; }

        [Output("Create permission")]
        public OutArgument<bool> cpP { get; set; }

        [Output("Read permission")]
        public OutArgument<bool> rpP { get; set; }

        [Output("Write permission")]
        public OutArgument<bool> wpP { get; set; }

        [Output("Delete permission")]
        public OutArgument<bool> dpP { get; set; }

        [Output("Append permission")]
        public OutArgument<bool> apP { get; set; }

        [Output("AppendTo permission")]
        public OutArgument<bool> atpP { get; set; }

        [Output("Assing permission")]
        public OutArgument<bool> aspP { get; set; }

        [Output("Share permission")]
        public OutArgument<bool> shpP { get; set; }

        protected override void Execute(CodeActivityContext executionContext)
        {
            ITracingService tracer = executionContext.GetExtension<ITracingService>();
            IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
            IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
            IOrganizationService service = serviceFactory.CreateOrganizationService(null);

            EntityReference target;

            String entity = entityP.Get(executionContext);
            String guid = guidP.Get(executionContext);

            if (!String.IsNullOrEmpty(entity) && !String.IsNullOrEmpty(guid))
                target = new EntityReference(entity, new Guid(guid));
            else
                target = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId);

            EntityReference user = userP.Get(executionContext);
            if (user == null)
                user = new EntityReference("systemuser", context.InitiatingUserId);

            RetrievePrincipalAccessRequest req = new RetrievePrincipalAccessRequest();
            req.Principal = user;
            req.Target = target;
            RetrievePrincipalAccessResponse resp = (RetrievePrincipalAccessResponse)service.Execute(req);

            cpP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.CreateAccess));
            rpP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.ReadAccess));
            wpP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.WriteAccess));
            dpP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.DeleteAccess));
            apP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.AppendAccess));
            atpP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.AppendToAccess));
            aspP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.AssignAccess));
            shpP.Set(executionContext, resp.AccessRights.HasFlag(AccessRights.ShareAccess));
        }
    }
}

自定义操作

在 SystemUser 实体上创建自定义操作。 添加输入输出参数如下(抱歉截图中没有使用英文,我们是意大利语):

调用操作

终于可以通过javascript调用动作了:

var readOnly;
var params = {
    "entita": Xrm.Page.data.entity.getEntityName(),
    "guid": Xrm.Page.data.entity.getId().slice(1, -1)
};
$.ajax({
    url: Xrm.Page.context.getClientUrl() + "/api/data/v8.1/systemusers(" + Xrm.Page.context.getUserId().slice(1, -1) + ")/Microsoft.Dynamics.CRM.new_controllaprivilegi",
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    data: JSON.stringify(params),
    type: "post",
    dataType: "json",
    async: false,
    success: function (_responseOfferta) {
        readOnly = !_responseOfferta["Write"];
    }
});

希望对您有所帮助!