Mostrando postagens com marcador visual studio. Mostrar todas as postagens
Mostrando postagens com marcador visual studio. Mostrar todas as postagens

Consumindo Web-Service PHP através do ASP.NET (C#)

Já passou por aqui um post sobre de como consumir um web-service, mas era em ASP.NET. Agora como consumir um web-service em PHP? Da mesma forma. Não muda! O fato de escrever esse post é apenas e pelo simples fato de ter um certo inconveniente na elaboração do web-service em PHP.
Se procurar na net, recomendo o artigo de Maurício Reckziegel da iMasters que é muito bom e explica certinho como fazer. Se você seguir à risca o que está escrito irá conseguir elaborar um web-service em PHP normalmente e irá conseguir consumir, menos em ASP.NET. Não é que a matéria esteja errada, é porque o ASP.NET é chato com a validação do WSDL que é gerado pelo PHP. O documento (WSDL) tem que ser gerado na mão e, quando não é gerado de forma automática, estamos susceptíveis ao erro. Com o web-service em PHP é assim...
Então, digamos que você tenha elaborado o web-service em PHP e já fez referência na sua aplicação. Contudo sua aplicação pode dar erro ou retornar nada. Primeiramente, todo WSDL que iremos usar deve ser validado antes de ser devidamente consumido. O Visual Studio dispõe de uma ferramenta que valida e gera a classe consumidora (que não precisar ser usada pois está intrínseco na ferramenta). Vá em Iniciar > Todos os Programas > Microsoft Visual StudioVisual Studio ToolsVisual Studio 2008 Command Prompt. Irá abrir um prompt de comando. Escreva por exemplo: wsdl http://thiagomarcal.blogspot.com/webservice.php?wsdl . Se der tudo certo, irá surgir um resultado semelhante a esse:


Se estiver tudo OK, então pode usar tranquilamente, caso contrário irá surgir o seguinte problema:

Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 2.0.50727.3038]
Copyright (C) Microsoft Corporation. All rights reserved.

Warning: This web reference does not conform to WS-I Basic Profile v1.1.

Ou seja, o WSDL gerado pelo PHP não está conforme o padrão. Dando uma alterada aqui e ali, podemos usar o seguinte código para gerarmos o web-service em PHP dentro dos conformes:

<?php
// Requerimento aos componentes
require_once('nusoap/nusoap.php');
include("class.phpmailer.php");
include("class.smtp.php");


// Criação da instância
$server = new soap_server();


// Registro do método
$server->register('EnviaMail');


// WSDL
$server->configureWSDL('server.EnviaMail','urn:server.EnviaMail');
$server->wsdl->schemaTargetNamespace = 'urn:server.EnviaMail';
// registra o método a ser oferecido
$server->register('EnviaMail', //nome do método
array('email' => 'xsd:string'), //parâmetros de entrada
array('return' => 'xsd:string'), //parâmetros de saída
'urn:server.EnviaMail', //namespace
'urn:server.EnviaMail#EnviaMail', //soapaction
'rpc', //style
'literal', //use
'Retorna se o e-mail foi enviado' //documentação do serviço
);


// Definição do método a ser utilizado
function EnviaMail($email) {
return "E-email enviado com sucesso!";
}


// Requisição para uso do serviço
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

Perceberam a diferença? Praticamente nenhuma, mas há: o estilo do documento. Não irei entrar em detalhes, mas dois tipos de documentos mais usados: encoded e literal (veja mais nesse artigo). Use literal! Com isso seu web-service será consumido certinho...
Se estiver com o erro: O cliente encontrou o tipo conteúdo de resposta de ' text/html; charset = utf-8 ', mas era esperado 'text/xml' ou The client find the answer 'text/html', but was expected 'text/xml'. verifique se seu web-service está imprimindo conteúdo HTML (echo) e comprometendo o retorno dos dados. Tranquilo, né?

Utilizando função de uma DLL Externa no SQL Server

Esse é um tópico que irá mostrar algo que definitivamente você já precisou mas não sabia como fazer e que facilitará (e muito) alguns trabalhos. Programadores que usam o Bando de Dados para programar sendo por Stored Procedure, Functions e Triggers já passaram por maus bocados para preparar um algoritmo que realizasse um determinado processo, mas que esse mesmo algoritmo é mais fácil de ser escrito (ou possuir funcionalidades que o SGDB não possui) em outra linguagem de programação. Por exemplo: validar e-mail. É possível no SQL Server fazermos um Function que receba um VARCHAR e retorne um BIT informando que um e-mail é válido ou não, contudo seria uma função um tanto que trabalhosa para quem não está familiarizado com programação em banco. Para quem desenvolve em ASP.NET (C# ou VB.NET) basta usarmos expressão regular que, em duas linhas, resolve o problema. Portanto iremos utilizar uma função escrita em C# compilada em uma DLL e usarmos em um Function no SQL Server. Isso é possível através do CLR.
Primeiramente vamos criar a DLL contendo a função (no nosso exemplo vamos fazer a que valida e-mail - mas você pode desenvolver a que quiser). Abra o Visual Studio e crie um Project. Em Project Type escolha Visual C# Windows e o Template opte por uma Class Libary. Note que quando você cria uma classe vem com o nome Class1.cs. Para facilitar a compreensão, renomeie para FuncoesSql.cs (ou outra) e remova o namespace criado. Agora, escreva a função que deseja e adicione os namespaces necessários ficando da seguinte forma:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;

public partial class FuncoesSql
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlBoolean IsMailValido(SqlString email)
    {
        // Cria um objeto de expressões regulares para validar e-mail
        Regex expressaoRegular = new Regex(@"^(([^<>()[\]\\.,;:\s@\""]+"
        + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)(\"".+\""))@"
        + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
        + @"\.[0-9]{1,3}\])(([a-zA-Z\-0-9]+\.)+"
        + @"[a-zA-Z]{2,}))$");

        // Realiza um teste na validação da expressão
        return new SqlBoolean(expressaoRegular.IsMatch(email.ToString()));
    }
}

No caso, precisamos explicitar os tipos de entrada e saída utilizados pelo banco de dados para que não haja problemas de tipagem. Poderia ser qualquer função ou quantas que quisesse, contanto que respeite os tipos. Agora compile a DLL pressionando F6 ou pelo menu Build. Já temos a DLL com a função. Copie a DLL (que está na pasta bin\Debug de sua solução) e coloque-a em um local onde seu Banco de Dados possa buscá-la. Para exemplo, colocarei em C:\SqlDlls\ no Servidor.
O próximo passo é verificar se no SQL Server está ativo a funcionalidade CLR, para isso vá em Iniciar > Todos os Programas > Microsft SQL Server 2008 (ou 2005) > Configuration Tools > SQL Server Surface Area Configuration. Entre em Surface Area Configuration for Features e na guia CLR Integration verifique se a função está habilitada. Se não estiver, habilite.


Dê OK e agora já poderá usar CLR no SQL Server. Abra o SQL Server Management Studio, conecte-se na base desejada e execute as seguintes instruções SQL (abra um New Query para isso):

-- CRIA O ASSEMBLY INDICANDO SUA ORIGEM
CREATE ASSEMBLY FuncoesSql FROM 'C:\SqlDlls\FuncoesSqlServerASPNET.dll'
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- CRIA A FUNÇÃO
CREATE FUNCTION dbo.Fun_Valida_Mail (@email NVARCHAR(350))
RETURNS BIT
-- INDICA A ORIGEM DA FUNÇÃO SQL: ASSEMBLY > CLASSE > FUNÇÃO
AS EXTERNAL NAME [FuncoesSql].FuncoesSql.IsMailValido
GO

Agora execute a Query (ou pressione F5)... Foi criada a função! Pronto... agora é só usar como se fosse uam função do SQL Server normalmente. Abaixo tem alguns exemplos de consulta e seus retornos:

Execuções:
SELECT dbo.Fun_Valida_Mail('tmarcal@gmail')
SELECT dbo.Fun_Valida_Mail('tmarcal@gmail.com')
SELECT dbo.Fun_Valida_Mail('tmarcal.. @gmail.com')
 
Retorno:
0
1
0
 
Apesar do trabalho inicial, pode-se aproveitar muito de ambos os recursos e criar cada vez mais funções complexas. Quanto ao desempenho da CLR, em comparação ao T-SQL, deve-se ficar a mesma coisa. A diferença é praticamente imperceptível. Espero que tenham gostado... Até breve!

Criando um Chat em ASP.NET em 1 minuto

Para quem quer ter um chat em seu web site, esse componente é uma mão na roda. Muito fácil de ser utilizado e configurado, apesar de seus bugs (irei solucioná-los no fim do post). Em poucos segundos você tem um chat funcional! A Web Furbish desenvolveu esse componente e pode ser encontrado tanto aqui quanto aqui e em vários mirros pela net. Vamos ao desenvolvimento...
Extraia os arquivos em um local onde poderá buscá-los. Agora crie um novo Web Site. Se for sua primeira vez usando o componente, primeiramente, deve-se adicionar o novo controle ao ToolBox do Visual Studio. Para isso, clique com o botão direito em algum local onde é exibido os itens e escolha a opção Choose Items:


Quando surgir a caixa de seleção de componentes, na aba .NET Framework Components, clique no botão Browse... para selecionar a DLL JaxterChat.dll na pasta onde extraiu os arquivos a princípio. Clique em OK para carregá-la. Verá que ela foi adicionada ao ToolBox. Esse passo foi o mais difícil! Em seguida copie a pasta JaxterChat (que havia junto à DLL) e incorpore-o a seu projeto. Nessa pasta contêm arquivos de imagem, som, etc. Agora é simples: arraste-o para a página para que ele seja adicionado. Pronto! Você já tem seu chat...
O resto é apenas configuração: tema, tempo de atualização, usar som, nome dos labels, etc. Veja como ficou o meu!


Tranquilo e prático, não? Antes dos bugs, vamos a alguns questionamentos?

1) Como faço para ter várias salas?

Você não precisar criar várias páginas para a cada sala. Basta que, no Page_Load, atribua o nome da sala ao controle. Exemplo: Chat.RoomName = "Blog"; O controle irá se encarregar de fazer a separação dos usuários de acordo com o nome da sala.

2) Como gravar o log das conversas?

Crie um método para o OnMessagePosted do chat. Você pode gravar em banco ou em arquivo. Ficaria mais ou menos assim:

protected void Grava_Log(object sender, WebFurbish.JaxterMessageEventArgs e)
{
      string sala = e.RoomName;
      string usuario = e.UserName;
      string mensagemExibida = e.Message;
      string mensagemHtml = e.MessageHTML;
      string hora = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");
      // Grava o log em banco ou em arquivo
}
 
3) Como enviar mensagens às salas (avisos de administração, etc) igual a um Broadcast?
 
Esse é um pouco mais complicado e demorado, então irei explicar em linhas gerais como seria:
  • Pegaria todas as sala usando o método GetRoomList();
  • E para cada sala faz-se o envio através do método SendCustomMessage().
Um exemplo seria: Chat.SendCustomMessage("Nova notícia no blog!", "Administração", "Blog", false);
O parâmetro false indica que essa mensagem não será processada em log (ou seja, não parassá pelo método do OnMessagePosted).
 
E n formas que há de customizar o chat para trabalhar da forma como desejar. Pois bem, agora vamos aos bugs encontrados. Quando levantei esses bugs enviei um e-mail para eles mas não obtive resposta até o momento (também nem tentei mais... :P).

Bug 1: A cada mensagem entrada, a barra de rolagem ao invés de acompanhar as mensagens, ela fica sempre apontada para o topo. Ou seja, ela não desce...

Notamos isso quando começa a encher de mensagens. A barra ao invés de rolar automaticamente para baixo, fica estagnada no topo. Analisando o JavaScript que ele gera, verifiquei que há um problema na função WF_goToBottomScroll. Daí, como não posso apagar ela, criei uma outra com o mesmo nome. Como há sobrecarga ela será executada também. É armengue, mas é uma solução. Como funciona essa solução? A cada 0 segundos verifico se o foco está no campo de texto digitado: se estiver, a barra da div rola automaticamente para baixo. Para que isso funcione, baixe esse script aqui para fazer uma varredura de controles HTML. E adicione o seguinte bloco de código JS na página que contêm o chat:

window.onload = function() {
    setFocusTracking();
    sizeMsgOut = document.getElementById('WF_msgOut').scrollHeight;
    setTimeout("WF_goToBottomScroll('WF_msgOut');", 0);
}


function WF_goToBottomScroll(elemento) {
    var msgOut = document.getElementById(elemento);
    if (document.hasFocus) {
        if (document.hasFocus.id == 'WF_textInput')
            msgOut.scrollTop = msgOut.scrollHeight;
    }
    setTimeout("WF_goToBottomScroll('" + elemento + "');", 0);
}

Bug 2: O som não funciona!

Quando vi que iria ter som, pensei: "Bala!". Mas daí ele exige Java para rodar. Pensei novamente: "Tranquilo! Hoje na net, em sites de banco, tem que ter Java, logo pro chat vai ser pré-requisito ter também.". Instalei a versão mais recente e não funcionou! Porque, eu não sei. Como o componente é fechado, a única coisa que deu para ver é que ele chama uma classe Java SoundApplet.class já compilada. Enfim, providenciei outra solução: coloquei a propriedade EnableSound como false e adicionei algumas linhas ao script WF_goToBottomScroll para tocar um som a cada vez que é dado uma entrada de mensagem. Esse som é puro JavaScript! Primeiro, adicione uma tag de som em background em qualquer local da página, assim:

<BGSOUND id="sound" src="">

Depois crie uma variável global var sizeMsgOut = 0; antes do window.onload . Ou seja, estou criando uma variável global que irá armazenar o tamanho de minha div a cada momento e quando entrar na página pela primeira vez terá valor 0. Agora, adicione as linhas abaixo na função WF_goToBottomScroll antes do setTimeout:
if (document.getElementById('WF_msgOut').scrollHeight != sizeMsgOut) {
    document.all.sound.src = "JaxterChat/Sounds/alert.au";
    sizeMsgOut = document.getElementById('WF_msgOut').scrollHeight;
}

A cada iteração da função, verifico se o tamanho da div que contêm as mensagens é diferente do valor armazenado na variável. Se for é porque entrou nova mensagem logo deve tocar o som.

Esses foram dois bugs que encontrei quando estava usando-o. Pode ser que haja outros que não encontrei. Se não tiver é bom, pois é um chat bem legalzinho e fácil e manipular. Até mais!

"Crash" nos Templates do Visual Studio - Parte 2

Quem leu o primeiro post do "Crash" de Templates do Visual Studio deve ter visto que esse não foi o erro que aconteceu comigo (você que está lendo, digo)... Outro erro tem assombrado programadores quando é emitido uma mensagem como essa:
"Package 'Visual Web Developer HTML Source Editor Package' has failed to load properly ( GUID = {BFCC0C3C-6F87-4285-A6C8-BB616061800D} ). Please contact package vendor for assistance. Application restart is recommended, due to possible environment corruption. Would you like to disable loading this package in the future? You may use 'devenv /resetskippkgs' to re-enable package loading."
Essa e suas variantes ficam informando esse erro e pedindo para executar o comando devenv /resetskippkgs para reabilitar os pacotes de volta. Muito bem, eu já havia ensinado em um post anterior como realizar a execução desse tipo de comando. Mas supondo que você executou o procedimento, abre de novo o Visual Studio e o erro persiste... e agora?
 
Bem, provavelmente você irá fazer algumas das sugestões recomendadas anteriormente, contudo descobri o seguinte: algumas instalações fazem com que a linguagem do Visual Studio fique em português (perceba se a aplicação está com o menu ou partes em português), por exemplo, quando feito a instalação de algum Add-on, e faz com que aconteça esse tipo de crash.
 
O Visual Studio não trabalha bem com outro tipo de linguagem a não ser o inglês devido a variantes que ele possui bem como o funcionamento dos controle e reconhecimento do parse da linguagem. Então, devemos colocar o Visual Studio de volta para a linguagem padrão e para isso realize os seguintes passos:
  1. Abra o Visual Studio;
  2. Entre em Tools e em seguida escolha Options;
  3. Caso todas as opções não estejam sendo exibidas, clique em "Show all settings";
  4. Em Environment e escolha o item International Settings;
  5. Selecione a linguagem Inglês (English) e clique em OK;
  6. Feche o Visual Studio;
  7. Execute o comando devenv /resetskippkgs conforme explicado anteriormente.
Com isso, o problema já estará corrigido. Ai você diz: "Mas as opções você escreveu em Inglês? E no meu aparece em Português...". Mais fácil do que isso é impossível! Google está aí pra isso... Boa sorte!

"Crash" nos Templates do Visual Studio

Ontem, quando estava instalando um componente no Visual Studio, tudo funcionava normalmente como um dia qualquer. Não me esperava o Visual Studio falhar na hora que mais precisava dele. Ao trabalhar em um projeto e adicionar um novo item, todos os templates sumiram!!! Não podia selecionar nenhum template (óbvio que não poderia criar mais nada) e ao mesmo tempo surgia-se um erro bizarro informando para que eu entrasse no visualizador de eventos para obter com mais detalhes.

Chegando lá aparecia um erro informando que houve uma falha no carregamento dos templates e que era para executar o comando abaixo para fazer uma recuperação dos templates:

devenv.exe /installvstemplates

Para executar o comando, vá em Iniciar, depois em Programas escolha a pasta do Microsoft Visual Studio 2008/2005, depois na Visual Studio Tools e clique no prompt Visual Studio 2008/2005 Command Prompt. Entre com o comando descrito acima e dê Enter. Aparentemente o comando é executado sem problemas e rapidamente. Só que tem uma coisa: volte a abrir o Visualizador de Eventos (para quem não sabe o Visualizador de Eventos encontra-se no Painel de Controle - Ferramentas Administrativas) e monitore os eventos que estão sendo gerados. Espere um instante e veja se nenhuma entrada foi gerada. Se der tudo certo, no máximo, irá surgir alguns warnings no log mas que pouco afeta a restauração.

E, por mais que queremos, uma coisa nunca funciona na primeira vez. Logo que executei apareceu inúmeros erros (nem eram warnings). Abri o Visual Studio e continuava a mesma coisa. Li alguns materiais na Internet e notei que algumas pessoas já se depararam com esse problema. Encontrei vários métodos para lidar com a situação, mas pensei melhor e fiquei com receio de piorar o que já estava estragado. Então fiz o que todo brasileiro gosta de fazer: tentar de novo! Executei o mesmo processo e funcionou! Aparentemente estava tudo de volta...

Obs: Feche todas as instâncias do Visual Studio senão não funciona corretamente.

Para quem tiver essa sorte, verifique se está tudo nos conformes. Quem não conseguiu recomendo fortemente reinstalar o Visual Studio novamente. Senão, tente alguns dos tutoriais espalhados pela net. Alguns procedimentos como os descritos abaixo podem ajudar caso não resolva baseando-se nos métodos acima:
  1. Mudar o diretório dos templates na configuração do Visual Studio;
  2. Verifique se os templates necessários existem na pasta "C:\Program Files\Microsoft Visual Studio 9\Common7\IDE\ProjectTemplates" e "ItemTemplates"
Outra solução drástica é fazer a restauração do sistema para um ponto onde estava funcionando corretamente a aplicação. Boa sorte!