Algo que eu procuro sempre aqui no trabalho é facilitar a vida do usuário. Coisinhas pequenas, como completar o endereço a partir do cep, podem poupar um bom tempo de quem faz isso dezenas de vezes no dia.
Ao código:
Achei um monte de webservices oferecendo esse serviço. Escolhi esse, em php: web service consulta de endereço. Se você nunca usou webservice no visual studio, leia esse artigo antes de continuar.
Adicione a referência ao wsdl no seu projeto, e a cláusula using na sua unit.
Código simples que recupera os dados:
CEPService _servico = new CEPService();string[] resultado = _servico.obterLogradouro(cep).Split(',');//Quando o cep não é encontrado, a resposta do servidor vem no formato // "CEP cep NAO ENCONTRADO" ou "Cep cep não encontrado" if (resultado[0].StartsWith("cep", StringComparison.OrdinalIgnoreCase) throw new CepNotFoundException("Cep não foi encontrado!"); //Quando o cep é encontrado, a resposta vem no formato // "LOGRADOURO, BAIRRO, CIDADE, ESTADO" Console.WriteLine("Logradouro: " + resultado[0].Trim()); Console.WriteLine("Bairro: " + resultado[1].Trim()); Console.WriteLine("Cidade: " + resultado[2].Trim()); Console.WriteLine("Estado: " + resultado[3].Trim());
Código modificado pra retornar um objeto endereço e fazer um cache bem básico:
(O construtor de Endereco tem a assinatura:
public Endereco(string cep, string logradouro, string numresidencial, string bairro, string cidade, string estado))
public class EnderecoHelper {private static CEPService _servico = new CEPService(); //Armazena os endereços de cep que não foram encontrados no banco,//pra não pesquisar duas vezes private static IList _invalidos = new List();//Número máximo de ceps inválidos que vai ser guardada private const int MAXINVALIDOS = 15;//Último cep pesquisado. Útil caso o mesmo cep seja //pesquisado várias vezes seguidasprivate static Endereco _ultimoEndereco = new Endereco; private static string _cep; public static Endereco getEndereco(string cep) { if (cep.Equals(_ultimoEndereco.cep)){ return _ultimoEndereco;} if (_invalidos.Contains(cep)) { return null;} string[] resultado = _servico.obterLogradouro(cep).Split(','); if (!resultado[0].StartsWith("cep", StringComparison.OrdinalIgnoreCase)) { _ultimoEndereco = new Endereco(cep, resultado[0].Trim(), "", resultado[1].Trim(), resultado[2].Trim(), resultado[3].Trim());return _ultimoEndereco; }else {_invalidos.Add(cep); if (_invalidos.Count > MAXCOUNT){ _invalidos.Clear();} return null;} }}
Ainda tem um monte de coisas que eu quero fazer pra melhorar isso aí. Alguns itens: Aumentar o tamanho do cache de resultados pesquisados (substituir o _ultimoEndereco por uma lista), implementar a lista de ceps inválidos como uma queue, chamar o webservie assíncronamente.
Assim que eu tiver mais tempo livre aqui no trampo eu faço isso, já que não é tão prioritária.
Espero ter ajudado alguém!