Pessoal,
Conforme prometido, a continuidade do post anterior sobre Web API que foi lançada para o CRM 2016. Se você ainda não leu meu post anterior, recomendo que o veja primeiro:
CRM 2016 – Microsoft Dynamics CRM Web API
Bom, no post anterior deixei uma explicação sobre o que são os Web API, bem como um pouco de fatos e minhas impressões do que teremos daqui por diante. Agora irei, criar alguns exemplos de como utilizar o Web API em um Web Resource!
Primeira vamos ao objeto XMLHttpRequest! Além de usarmos como “method” de seu header o “GET” ou “POST”. Temos outros tipos de methods, como “PUT” (Update do valor de uma única Propriedade), “PATCH” (Upsert e Update), “DELETE” (Delete e Delete do valor de uma única Propriedade). Outro ponto seria o valor do “status” de retorno da chamada, usamos o “200”, mas muitos methods retornam no “204” (204 ocorre quando não temos um retorno, a operação ocorreu com sucesso, mas sem retorno). Por isso, fiquem atentos!
Como este post estamos falando de utilizar a Web API dentro de um Web Resource, temos como facilidade de que não é preciso nos conectar ao CRM, pois a autenticação e autorização é transparente para o desenvolvimento.
Fiz algo bem simples, mas que nos possibilita um exemplo das principais funcionalidades. Criei um botão para cada uma:
Primeiramente é preciso adicionar uma referencia da página “ClientGlobalContext.js.aspx”
Agora, vamos aos códigos!
Create
function CreateAccount() { var contactid = "5BAF9899-F0E8-E511-80D4-C4346BDC11C1"; var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); req.open("POST", encodeURI(clientURL + "/api/data/v8.0/accounts"), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) { var accountUri = this.getResponseHeader("OData-EntityId"); console.log("Created account with URI: " + accountUri); document.getElementById("text").innerHTML = "Account created! URI " + accountUri; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(JSON.stringify({ name: "Sample account", description: "Description", fax: "44445555", "primarycontactid@odata.bind": "/contacts(" + contactid +")" })); }
Retrieve
function RetrieveAccounts() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue&$orderby=name asc"; req.open("GET", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 200)//to verify result is OK { var data = JSON.parse(this.response); if (data != null) { var result = " <table border='1'>"; for (var i = 0; i < data.value.length; i++) { result += " <tr> <td>" + data.value[i].name + "</td> </tr> "; } result += "</table> "; document.getElementById("text").innerHTML = result; } } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(null); }
Upsert
function UpsertAccount() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(D4147C41-E7F1-E511-80D6-C4346BDC4281)"; req.open("PATCH", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); //req.setRequestHeader("If-Match", "*"); // If you want to prevent the INSERT //req.setRequestHeader("If-None-Match", "*"); // If you want to prevent the UPDATE req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Updated account"); document.getElementById("text").innerHTML = "Account Updated!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(JSON.stringify({ fax: "1122223333", description: "Another Description" })); // Add an Entity object OR all properties that you want }
Update do valor de uma única Propriedade
function UpdateAccountProperty() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(D4147C41-E7F1-E511-80D6-C4346BDC4281)/description"; req.open("PUT", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Updated account property"); document.getElementById("text").innerHTML = "Property 'Description' Updated!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(JSON.stringify({ value: "New Description" })); // must the property "value" have to be used }
Delete
function DeleteAccount() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(92AA5510-EBF1-E511-80D6-C4346BDC4281)"; req.open("DELETE", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Deleted account"); document.getElementById("text").innerHTML = "Account Deleted!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(null); }
Delete do valor de uma única Propriedade
function DeleteAccountProperty() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(D4147C41-E7F1-E511-80D6-C4346BDC4281)/description"; // After the ID inform the field that have to be deletd req.open("DELETE", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Deleted account property"); document.getElementById("text").innerHTML = "Property 'Description' Deleted!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(null); }
O código completo:
<html> <head> <script type="text/javascript" src="ClientGlobalContext.js.aspx"></script> <script> function CreateAccount() { var contactid = "5BAF9899-F0E8-E511-80D4-C4346BDC11C1"; var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); req.open("POST", encodeURI(clientURL + "/api/data/v8.0/accounts"), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) { var accountUri = this.getResponseHeader("OData-EntityId"); console.log("Created account with URI: " + accountUri); document.getElementById("text").innerHTML = "Account created! URI " + accountUri; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(JSON.stringify({ name: "Sample account", description: "Description", fax: "44445555", "primarycontactid@odata.bind": "/contacts(" + contactid +")" })); } function RetrieveAccounts() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue&$orderby=name asc"; req.open("GET", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 200)//to verify result is OK { var data = JSON.parse(this.response); if (data != null) { var result = " <table border='1'>"; for (var i = 0; i < data.value.length; i++) { result += " <tr> <td>" + data.value[i].name + "</td> </tr> "; } result += "</table> "; document.getElementById("text").innerHTML = result; } } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(null); } function UpsertAccount() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(D4147C41-E7F1-E511-80D6-C4346BDC4281)"; req.open("PATCH", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); //req.setRequestHeader("If-Match", "*"); // If you want to prevent the INSERT //req.setRequestHeader("If-None-Match", "*"); // If you want to prevent the UPDATE req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Updated account"); document.getElementById("text").innerHTML = "Account Updated!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(JSON.stringify({ fax: "1122223333", description: "Another Description" })); } function UpdateAccountProperty() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(D4147C41-E7F1-E511-80D6-C4346BDC4281)/description"; req.open("PUT", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Updated account property"); document.getElementById("text").innerHTML = "Property 'Description' Updated!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(JSON.stringify({ value: "New Description" })); // must the property "value" have to be used } function DeleteAccount() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(92AA5510-EBF1-E511-80D6-C4346BDC4281)"; req.open("DELETE", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Deleted account"); document.getElementById("text").innerHTML = "Account Deleted!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(null); } function DeleteAccountProperty() { var clientURL = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); var query = "accounts(D4147C41-E7F1-E511-80D6-C4346BDC4281)/description"; // After the ID inform the field that have to be deletd req.open("DELETE", encodeURI(clientURL + "/api/data/v8.0/" + query), true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 204) {// status 204 console.log("Deleted account property"); document.getElementById("text").innerHTML = "Property 'Description' Deleted!"; } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; req.send(null); } </script> </head> <body style="word-wrap: break-word;"> <input type="button" value="Create Account" onclick="CreateAccount()" /> <input type="button" value="Retrieve All Accounts" onclick="RetrieveAccounts()" /> <input type="button" value="Upsert Account" onclick="UpsertAccount()" /> <input type="button" value="Update Account Property" onclick="UpdateAccountProperty()" /> <input type="button" value="Delete Account" onclick="DeleteAccount()" /> <input type="button" value="Delete Account Property" onclick="DeleteAccountProperty()" /> <div id="text"></div> </body> </html>
Bom é isso, em um post futuro, vou tentar criar um aplicação externa que acesse a Web API.
Para maiores informações:
Use the Web API with web resources
Perform operations using the Web API
GetGlobalContext function and ClientGlobalContext.js.aspx (client-side reference)
Authenticate to Microsoft Dynamics CRM with the Web API
[]’s,
Tiago Cardoso
Olá, muito bom o post e no momento certo, já que estou precisando disso no momento. Porém estou com uma dúvida:
Tenho um campo do tipo consulta, como passo esse valor para o Create?
CurtirCurtir
Olá Sthefanny, muito obrigado por ler o que eu escrevo!
Bom, realmente falta esta informação no meu post (já atualizei!), para o exemplo de Conta com um contato primário, seria algo assim:
Veja a muda um pouco como passamos, devemos concatenar o nome do atributo + “odata.bind” e depois passsar o serviço que representa a entidade que está sendo relacionada “/contact(‘GUID’)”
Eu localizei esta sintase aqui:
Associate entities on create
Em Composing JSON data to send, tem um exemplo melhor do que eu, pois faz uso de um objeto que representa o registro da entidade por completo, do modo que faço atrapalharia o reaproveitamento do código!
Obrigado novamente!
[]’s,
Tiago
CurtirCurtir
Valeu mesmo!
CurtirCurtir