sexta-feira, 25 de setembro de 2009

CustomValidator e PageMethods

Olá,

Hoje precisei utilizar uma rotina antiga criada por mim (ainda da época do ATLAS) para usar CustomValidator com PageMethods.

Acontece que, ao testar mais profundamente a página, encontrei alguns bugs oriundos do fato das chamadas serem assíncronas.
Não que minha rotina antiga não previsse isso, mas fazia um workarround (para não dizer gato) que falhava em algumas situações específicas.

Bom, após alguma pesquisa encontrei um artigo no CodeProject (http://www.codeproject.com/KB/ajax/SynchronousAJAX.aspx) que solucionava isto fazendo uma chamada síncrona ao servidor.
O código está abaixo e minha customização foi mínima, apenas para facilitar a utilização final:

// Chama um webmethod.
function GetWebValidationMethod(metodo, argumentos) {
var pagina = '<%=Page.Request.Url.AbsolutePath%>';
metodo = pagina + '\\' + metodo;
var result = GetSynchronousJSONResponse(metodo, argumentos);
result = eval('(' + result + ')');
return result.d;
}

// Realiza chamadas síncronas.
function GetSynchronousJSONResponse(url, postData) {
var xmlhttp = null;
if (window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else if (window.ActiveXObject) {
if (new ActiveXObject("Microsoft.XMLHTTP"))
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
else
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
// to be ensure non-cached version of response
url = url + "?rnd=" + Math.random();
xmlhttp.open("POST", url, false); //false means synchronous
xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xmlhttp.send(postData);
var responseText = xmlhttp.responseText;
return responseText;
}

Para usar as rotinas, bastar seguir o exemplo abaixo para o script executado pelo CustomValidator:

function OnValidarFormatoCNPJCPF(source, args) {
var argumentos = '{"CNPJ":"' + args.Value + '"}';
args.IsValid = GetWebValidationMethod('ValidarCNPJ', argumentos);
}

Neste caso, os argumentos devem ser construídos como um objeto JSON e, ao chamar o método, passa-se o nome do webmethod e os argumentos.

Até a próxima, JP.