terça-feira, 1 de novembro de 2011

>> VS.NET 2010 - Snippet Designer Plugin

Realmente facilita a "vida" ter a possibilidade de inserção de um código template complexo e longo com apenas uma chamada de [Shortcut no Code View] do Visual Studio. Este conceito é muito usado e se chama [Code Snippet].

Basicamente para criar um [fragmento de código] efetuarmos os seguintes passos:

1 - Criamos um arquivo XML;
2 - Primeiro adicionamos o Elemento CodeSnippets;
3 - Logo após adicionamos a seção Header;
4 - Depois adicionamos mais um elemento (<Snippet>) que conterá o Código Template;
5 - E por fim, salvamos o arquivo com a extensão .SNIPPET, no diretório de snippets no Visual Studio, geralmente em [C:\Users\[UserName]\Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets].

Segue exemplo dos passos seguidos acima:



<CodeSnippets
xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>
My Snippet
</Title>
</Header>
<Snippet>
<Code Language="CSharp">
<![CDATA[MessageBox.Show("Hello World");]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>



Porém, para facilitar ainda mais a vida do desenvolvedor, segue a dica do [Snippet Designer] que aumenta mais ainda a produtividade de criação de snippets, usando a IDE do Visual Studio.

Por exemplo, uma vez que você criou um código reutilizável, e gostaria de transformá-lo em um Snippet, com este Plugin basta selecionar seu código e exportá-lo como um snippet, como mostra a imagem abaixo:



Existem mais recursos interessantes, que estão documentados no link para baixar o Plugin.

terça-feira, 13 de setembro de 2011

>> CRM 2011 - Busca de Dados do CRM via JScript-JQuery

Segue os procedimentos para utilizar este poderoso recurso do CRM 2011:

1 - Baixar o SDK do produto;

2 - Após extrair o SDK em qualquer diretório, ir até o sub-diretório [sdk\samplecode\js\restendpoint\jqueryrestdataoperations\jqueryrestdataoperations\scripts] e importar o arquivo [jquery1.4.1.min.js] como um [Web Resource] no CRM;

3 - Efetuar o mesmo procedimento do passo 2, para o arquivo [jqueryrestdataoperationfunctions.js];

4 - Ao associar estes Web Resources a entidade do CRM desejada, atente para a ordem, pois é relevante no carregamento da página:
4.1 - primeiro [jquery1.4.1.min.js];
4.2 - depois [jqueryrestdataoperationfunctions.js];
4.3 - por último, seu próprio JS, que utilizará os recursos acima.

P.S.: Apenas para lembrar o caminho, para efetuar o passo 4, abrir o formulário da entidade desejada e clicar no botão [Propriedades do Formulário], como exemplifica a tela abaixo:




5- No sub-diretório citado no passo 2, existe uma arquivo chamado [jqueryrestdataoperationactions.js] que contém diversos exemplos de uso. Segue abaixo um deles:




function retrieveAccount(id) {
// [retrieveRecord] está presente na biblioteca [jqueryrestdataoperationfunctions.js].
retrieveRecord(id, "AccountSet", retrieveAccountCompleted, null);
}

function retrieveAccountCompleted(data, textStatus, XmlHttpRequest) {
alert(data.Name);
}



Para trabalhar com buscas mais complexas, existe a função [retrieveMultiple]. Porém, infelizmente, não existe exemplo no SDK. Consegui achar um artigo muito bom chamado [Adding Selection Criteria to REST Queries in CRM 2011]. Testei um caso com sucesso. Vale realmente a pena checar.

>> CRM 4.0 - FetchXML via JScript

Segue código aprimorado (extraído do SDK - http://technet.microsoft.com/en-us/library/cc677073.aspx) para busca de qualquer informação do CRM, via JScript.



window.ExecFetchXML = function (entityName, column, conditionAttribute, operator, value, fieldOrderName, fieldOrderValue, page, count) {

var fetchMapping = "logical";
var filterType = "and";
var authenticationHeader = GenerateAuthenticationHeader();
var columnSplit = column.split(",");
var conditionAttributeSplit = conditionAttribute.split(",");
var operatorSplit = operator.split(",");
var valueSplit = value.split(",");

var xml = "<?xml version='1.0' encoding='utf-8'?>" +
"<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
authenticationHeader +
"<soap:Body>" +
"<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
"<fetchXml>&lt;fetch mapping='" + fetchMapping + "'";

if (page != null) xml += " page='" + page + "' ";
if (count != null) xml += " count='" + count + "' ";

xml += "&gt;&lt;entity name='" + entityName + "'&gt;";

if (columnSplit.length > 1) {
for (i = 0; i < columnSplit.length; i++) {
xml += "&lt;attribute name='" + String(columnSplit[i]) + "'/&gt;";
}
}
else {
xml += "&lt;attribute name='" + column + "'/&gt;";
}

if (fieldOrderName != null && fieldOrderValue != null) {
xml += "&lt;order attribute='" + fieldOrderName +
"' descending='" + fieldOrderValue + "'/&gt;";
}

if (conditionAttribute != null && operator != null && value != null) {
xml += "&lt;filter type='" + filterType + "'&gt;";

if (conditionAttributeSplit.length > 1) {
for (i = 0; i < conditionAttributeSplit.length; i++) {
xml += "&lt;condition attribute='" + conditionAttributeSplit[i] + "'" +
" operator='" + operatorSplit[i] + "' value='" + valueSplit[i] + "'/&gt;";
}
}
else {
xml += "&lt;condition attribute='" + conditionAttribute + "'" +
" operator='" + operator + "' value='" + value + "'/&gt;";
}

xml += "&lt;/filter&gt;";
}

xml += "&lt;/entity&gt;" +
"&lt;/fetch&gt;</fetchXml>" +
"</Fetch>" +
"</soap:Body>" +
"</soap:Envelope>";

// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);

// Capture the result.
var resultXml = xHReq.responseXML;

// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount == 0) {
// Capture the result and UnEncode it.
var resultSet = new String();
resultSet = resultXml.text;

resultSet = resultSet.replace("<resultset morerecords=\"0\" />", "");

if (resultSet != "") {
// Create an XML document that you can parse.
var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
oXmlDoc.async = false;
// Load the XML document that has the UnEncoded results.
oXmlDoc.loadXML(resultSet);

var retValue = null;

if (oXmlDoc.getElementsByTagName('result') != null) {

var objLen = oXmlDoc.getElementsByTagName('result').length;
retValue = new Array(objLen);

// Loop nas Linhas
for (j = 0; j < objLen; j++) {

retValue[j] = new Object();

if (columnSplit.length > 1) {
for (i = 0; i < columnSplit.length; i++) {
if (oXmlDoc.getElementsByTagName('result')[j].selectSingleNode(String(columnSplit[i])))
eval("retValue[" + String(j) + "]." + String(columnSplit[i]) + "= '" + oXmlDoc.getElementsByTagName('result')[j].selectSingleNode('./' + String(columnSplit[i])).text + "'");
}
}
else {

if (oXmlDoc.getElementsByTagName('result')[j].selectSingleNode(column))
eval("retValue[" + String(j) + "]." + column + "= '" + oXmlDoc.getElementsByTagName('result')[j].selectSingleNode(column).text + "'");

}
}
}
}
}

return retValue;

}



E as formas de utilização:



var result1 = window.ExecFetchXML('account', 'accountid, name', 'name', 'like', '%TESTE%', null, null, null, null);
alert(result1[0].accountid);
alert(result1[0].name);


/*
- Ordenado por [name];
- Ascendente [true];
- Retorna 2 páginas, com 10 clientes por página.
*/
var result2 = window.ExecFetchXML('account', 'accountid, name', 'name', 'eq', 'TESTE', 'name', 'true', 2, 10);

/*
- Busca por vários campos (name like '%TESTE%' e cnpj='12345678900');
*/
var result3 = window.ExecFetchXML('account', 'accountid, name', 'name,cnpj', 'like,eq', '%TESTE%,12345678900', null, null, null, null);

quinta-feira, 31 de março de 2011

>> CRM 4.0 - Erro de Abertura de Popups

Se você está se deparando com o seguinte erro no CRM:


Não foi possível abrir uma janela do Microsoft Dynamics CRM. É possível que ela tenha sido bloqueada por um bloqueador de pop-ups. Adicione este servidor Microsoft Dynamics CRM a lista de sites aos quais o seu bloqueador de pop-ups permite abrir novas janelas: <servidorcrm>




e já revisou (muitas vezes) as configurações do Internet Explorer, porém não encontrou a solução, segue mais uma dica importante:

- Pode acontecer que, ao tentar salvar um registro na entidade do CRM, algum [PLUGIN] esteja sendo executado; e se este plugin estiver usando a função:


// Gera um retorno de mensagem para o usuário do CRM (em um Popup).
throw new InvalidPluginExecutionException(MensagemErro);


Pode acontecer que a variável [MensagemErro] exceda o tamanho de [1900] caracteres, o que vai impossibilitar a passagem desta mensagem para a camada de [interface] do CRM, a qual deveria mostrá-la para o usuário.

Portanto, uma cadeia de caracteres muito grande, gera um erro "mentiroso" para o usuário!

Fiquem atentos CRM Developers!

[]s

terça-feira, 22 de março de 2011

>> DICA: Internet Information Services EXPRESS!

Quem desenvolve aplicações WEB, e já teve a necessidade de executar este tipo de aplicação em uma máquina [não-servidora], ou seja, que não contenha o [Internet Information Services] da Microsoft, deve estar familiarizado com o termo [Cassini Web Server], que justamente faz o papel do IIS.

Porém, como se sabe, esta aplicação é limitada, e consegue gerenciar aplicações que rodam sob o .NET Framework, até a versão 2.0 .

A boa notícia é que a Microsoft lançou uma versão [gratuita] do IIS, chamada IIS Express. Inclusive, nesta versão, é possível rodar aplicações que utilizam o .NET Framework 4.0 .

O blog do [Scott Guthrie] explica muito bem esta tecnologia.

[]s