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"];
}
});
希望对您有所帮助!
我无法检索对 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"];
}
});
希望对您有所帮助!