Usuário com melhor resposta
[Dynamics CRM 2011] Recuperar dados do PrincipalObjectAccess pelo javascript

Pergunta
-
Bom dia Galera,
$.ajax({
Estou tentando recuperar via o data pelo javascript o ObjectId passando o PrincipalId=TeamId na consulta. Não esta recuperando ninguém, nao sei por que! já que pra outras entidades recupero as informações da mesma maneira. Existe alguma forma específica para recuperar dados desta tabela pelo javascript?
Obs: PrincipalId = TeamId
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
async: false,
url: Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/PrincipalObjectAccessSet?$select=ObjectId&$filter=PrincipalId eq guid'"+TeamId+"'",
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
var sharedQueue = data.d;
ObjectId = sharedQueue.results[0].ObjectId;
}
});
Esta mesma consulta sendo feita no SQL retorna o o objeto desejado. Alguem pode me ajudar?
Respostas
-
Olá a Todos,
Obrigado Christophe, o objetivo era recuperar através da Equipe a Fila compartilhada dela.
Após vários dias de pesquisa, finalmente consegui.
Consegui recuperar os dados que eu queria da tabela Principal Object Access (POA) utilizando o FetchXML. Como resolvi meu problema?
1) Utilizei uma biblioteca ja existente FetchUtil.js (código mais abaixo).
2) E em um novo javascript criado por mim no Load do formulário executei o fetch para recuperar. Exemplo abaixo:
var _sOrgName = null; var _sServerUrl = null; // Recupero os dados da Organização e a URL do Dynamics. _sOrgName = Xrm.Page.context.getOrgUniqueName(); _sServerUrl = Xrm.Page.context.getServerUrl(); // Faço o fetch passando o TeamId da Equipe, solicitando da tabela todos os "Records"
// o PrincipalId é igual ao TeamId.
var sFetch = "<fetch mapping='logical'>" + "<entity name='principalobjectaccess'>" + "<attribute name='objectid' />" + "<attribute name='principalid' />" + "<filter type='and'>" + "<condition attribute = 'principalid' operator='eq' value='" + TeamId + "'/>" + "</filter>" + "</entity>" + "</fetch>";
//Recupero os dados do Fetch e jogo na variavel ObjectId, onde após realizar este
// procedimento consegui recuperar a Fila desejada fazendo uma query oData em outra
// tabela, já que o ObjectId é igual ao QueueId (Id da Fila).
var _oService = new FetchUtil(_sOrgName, _sServerUrl); var res =_oService.Fetch(sFetch); var objectId = (res[0].attributes["objectid"].value);Segue abaixo o código do FetchUtil.js
var XMLHTTPSUCCESS = 200; var XMLHTTPREADY = 4; function FetchUtil(sOrg,sServer) { this.org = sOrg; this.server = sServer; if (sOrg == null) { if (typeof(ORG_UNIQUE_NAME) != "undefined") { this.org = ORG_UNIQUE_NAME; } } if (sServer == null){ this.server = window.location.protocol + "//" + window.location.host; } } FetchUtil.prototype._ExecuteRequest = function(sXml, sMessage, fInternalCallback, fUserCallback) { var xmlhttp = new XMLHttpRequest(); xmlhttp.open("POST", this.server + "/XRMServices/2011/Organization.svc/web",(fUserCallback!=null)); xmlhttp.setRequestHeader("Accept", "application/xml, text/xml, */*"); xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"); if (fUserCallback!=null) { //asynchronous: register callback function, then send the request. var crmServiceObject = this; xmlhttp.onreadystatechange = function(){ fInternalCallback.call(crmServiceObject,xmlhttp,fUserCallback) }; xmlhttp.send(sXml); } else { //synchronous: send request, then call the callback function directly xmlhttp.send(sXml); return fInternalCallback.call(this,xmlhttp,null); } } FetchUtil.prototype._HandleErrors = function(xmlhttp) { /// <summary>(private) Handles xmlhttp errors</summary> if (xmlhttp.status != XMLHTTPSUCCESS) { var sError = "Error: " + xmlhttp.responseText + " " + xmlhttp.statusText; alert(sError); return true; } else { return false; } } FetchUtil.prototype.Fetch = function(sFetchXml, fCallback) { /// <summary>Execute a FetchXml request. (result is the response XML)</summary> /// <param name="sFetchXml">fetchxml string</param> /// <param name="fCallback" optional="true" type="function">(Optional) Async callback function if specified. If left null, function is synchronous </param> var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"; request += "<s:Body>"; request += '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">' + '<request i:type="b:RetrieveMultipleRequest" ' + ' xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts"' + ' xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' + '<b:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">' + '<b:KeyValuePairOfstringanyType>' + '<c:key>Query</c:key>' + '<c:value i:type="b:FetchExpression">' + '<b:Query>'; request += CrmEncodeDecode.CrmXmlEncode(sFetchXml); request += '</b:Query>' + '</c:value>' + '</b:KeyValuePairOfstringanyType>' + '</b:Parameters>' + '<b:RequestId i:nil="true"/>' + '<b:RequestName>RetrieveMultiple</b:RequestName>' + '</request>' + '</Execute>'; request += '</s:Body></s:Envelope>'; return this._ExecuteRequest(request,"Fetch", this._FetchCallback, fCallback); } FetchUtil.prototype._FetchCallback = function(xmlhttp,callback) { ///<summary>(private) Fetch message callback.</summary> //xmlhttp must be completed if (xmlhttp.readyState != XMLHTTPREADY) { return; } //check for server errors if (this._HandleErrors(xmlhttp)) { return; } var xmlReturn = xmlhttp.responseXML.xml; xmlReturn = xmlReturn.replace(/</g, '<'); xmlReturn = xmlReturn.replace(/>/g, '>'); results = xmlReturn; //return entity id if sync, or call user callback func if async if (callback != null) { callback(results); } else { return results; } }
- Marcado como Resposta Renan Albuquerque terça-feira, 28 de maio de 2013 17:39
Todas as Respostas
-
-
-
Olá,
Realmente não me é retornado nada também.
Qual seu objetivo final? Verificar se um registro foi compartilhado com uma determinada equipe?
Você pode fazer outros testes:
- Fazer sua requisição via SOAP (webservice) (com ou sem FetchXML). Considere dar uma olhada nesta lib xrmservicetoolkit.codeplex.com
- Verificar as possíveis mensagens (RetrieveUserPrivilegesRequest, etc.) relativas as entidades envolvidas
- Tentar outra abordagem: buscar as permissões e verificar se acesso é permitido com o registro em questão.
Mas é interessante você explicar o que quer fazer primeiro para avaliar uma possível solução.
Dê uma olhada nesse post: http://zhongchenzhou.wordpress.com/2012/06/29/dynamics-crm-2011-view-to-display-records-shared-with-current-user/
Virtual Group - Soluções Inteligentes www.virtualgroup.com.br -- Site brasileiro dedicado ao Dynamics CRM - www.DynamicsCRMWorld.net
- Editado Christophe Trevisani Chavey terça-feira, 28 de maio de 2013 16:17
-
Olá a Todos,
Obrigado Christophe, o objetivo era recuperar através da Equipe a Fila compartilhada dela.
Após vários dias de pesquisa, finalmente consegui.
Consegui recuperar os dados que eu queria da tabela Principal Object Access (POA) utilizando o FetchXML. Como resolvi meu problema?
1) Utilizei uma biblioteca ja existente FetchUtil.js (código mais abaixo).
2) E em um novo javascript criado por mim no Load do formulário executei o fetch para recuperar. Exemplo abaixo:
var _sOrgName = null; var _sServerUrl = null; // Recupero os dados da Organização e a URL do Dynamics. _sOrgName = Xrm.Page.context.getOrgUniqueName(); _sServerUrl = Xrm.Page.context.getServerUrl(); // Faço o fetch passando o TeamId da Equipe, solicitando da tabela todos os "Records"
// o PrincipalId é igual ao TeamId.
var sFetch = "<fetch mapping='logical'>" + "<entity name='principalobjectaccess'>" + "<attribute name='objectid' />" + "<attribute name='principalid' />" + "<filter type='and'>" + "<condition attribute = 'principalid' operator='eq' value='" + TeamId + "'/>" + "</filter>" + "</entity>" + "</fetch>";
//Recupero os dados do Fetch e jogo na variavel ObjectId, onde após realizar este
// procedimento consegui recuperar a Fila desejada fazendo uma query oData em outra
// tabela, já que o ObjectId é igual ao QueueId (Id da Fila).
var _oService = new FetchUtil(_sOrgName, _sServerUrl); var res =_oService.Fetch(sFetch); var objectId = (res[0].attributes["objectid"].value);Segue abaixo o código do FetchUtil.js
var XMLHTTPSUCCESS = 200; var XMLHTTPREADY = 4; function FetchUtil(sOrg,sServer) { this.org = sOrg; this.server = sServer; if (sOrg == null) { if (typeof(ORG_UNIQUE_NAME) != "undefined") { this.org = ORG_UNIQUE_NAME; } } if (sServer == null){ this.server = window.location.protocol + "//" + window.location.host; } } FetchUtil.prototype._ExecuteRequest = function(sXml, sMessage, fInternalCallback, fUserCallback) { var xmlhttp = new XMLHttpRequest(); xmlhttp.open("POST", this.server + "/XRMServices/2011/Organization.svc/web",(fUserCallback!=null)); xmlhttp.setRequestHeader("Accept", "application/xml, text/xml, */*"); xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"); if (fUserCallback!=null) { //asynchronous: register callback function, then send the request. var crmServiceObject = this; xmlhttp.onreadystatechange = function(){ fInternalCallback.call(crmServiceObject,xmlhttp,fUserCallback) }; xmlhttp.send(sXml); } else { //synchronous: send request, then call the callback function directly xmlhttp.send(sXml); return fInternalCallback.call(this,xmlhttp,null); } } FetchUtil.prototype._HandleErrors = function(xmlhttp) { /// <summary>(private) Handles xmlhttp errors</summary> if (xmlhttp.status != XMLHTTPSUCCESS) { var sError = "Error: " + xmlhttp.responseText + " " + xmlhttp.statusText; alert(sError); return true; } else { return false; } } FetchUtil.prototype.Fetch = function(sFetchXml, fCallback) { /// <summary>Execute a FetchXml request. (result is the response XML)</summary> /// <param name="sFetchXml">fetchxml string</param> /// <param name="fCallback" optional="true" type="function">(Optional) Async callback function if specified. If left null, function is synchronous </param> var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"; request += "<s:Body>"; request += '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">' + '<request i:type="b:RetrieveMultipleRequest" ' + ' xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts"' + ' xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' + '<b:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">' + '<b:KeyValuePairOfstringanyType>' + '<c:key>Query</c:key>' + '<c:value i:type="b:FetchExpression">' + '<b:Query>'; request += CrmEncodeDecode.CrmXmlEncode(sFetchXml); request += '</b:Query>' + '</c:value>' + '</b:KeyValuePairOfstringanyType>' + '</b:Parameters>' + '<b:RequestId i:nil="true"/>' + '<b:RequestName>RetrieveMultiple</b:RequestName>' + '</request>' + '</Execute>'; request += '</s:Body></s:Envelope>'; return this._ExecuteRequest(request,"Fetch", this._FetchCallback, fCallback); } FetchUtil.prototype._FetchCallback = function(xmlhttp,callback) { ///<summary>(private) Fetch message callback.</summary> //xmlhttp must be completed if (xmlhttp.readyState != XMLHTTPREADY) { return; } //check for server errors if (this._HandleErrors(xmlhttp)) { return; } var xmlReturn = xmlhttp.responseXML.xml; xmlReturn = xmlReturn.replace(/</g, '<'); xmlReturn = xmlReturn.replace(/>/g, '>'); results = xmlReturn; //return entity id if sync, or call user callback func if async if (callback != null) { callback(results); } else { return results; } }
- Marcado como Resposta Renan Albuquerque terça-feira, 28 de maio de 2013 17:39
-
Ótimo, já usei bastante também essa lib FetchUtil.
Mas a cada dia que passa é bem mais raro precisar escrever FetchXML.
Obrigado por compartilhar.
Virtual Group - Soluções Inteligentes www.virtualgroup.com.br -- Site brasileiro dedicado ao Dynamics CRM - www.DynamicsCRMWorld.net
- Editado Christophe Trevisani Chavey terça-feira, 28 de maio de 2013 17:41