Desenvolvimento - Web Services

Brincando com AJAX e SOAP na plataforma .NET

Neste artigo utilizaremos SOAP na versão 1.1 para implementarmos um exemplo prático.

por Diego Gazotto Dezembro



1. Introdução

SOAP (Simple Object Access Protocol) é um protocolo simples baseado em XML que surgiu devido à necessidade de integração de sistemas web e foi definido pelo w3c. Sua utilização independe da linguagem de programação ou plataforma.

Neste artigo utilizaremos SOAP na versão 1.1 para implementarmos um exemplo prático.

2. SOAP

O protocolo SOAP é um elemento XML que deve possuir elementos obrigatórios e alguns elementos opcionais.

2.1. Elementos obrigatórios

· Envelope: é a raiz da mensagem SOAP.

Exemplo:

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

...

</soap:Envelope>

· Body: este elemento contém a mensagem SOAP propriamente dita.

Exemplo:

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

<soap:Body>

...

</soap:Body>

</soap:Envelope>

2.2. Elementos opcionais:

· Header: contém informações especificas da aplicação. Obs: O Header deve ser o primeiro elemento do Envelope.

Exemplo:

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

<soap:Header>

...

</soap: Header>

<soap:Body>

...

</soap:Body>

</soap:Envelope>

· Fault: indica a ocorrência de um erro no processamento. Obs: O Fault deve estar dentro do elemento Body. O elemento Fault contém os seguintes “nós”:

faultcode – código do erro;

faultstring – descrição do erro;

faultactor – ator do erro;

detail – detalhes do erro.

Exemplo:

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

<soap:Header>

...

</soap: Header>

<soap:Body>

<soap:Fault>

<faultcode></faultcode>

<faultstring></faultstring>

<faultactor></faultactor>

<detail></detail>

</soap:Fault>

...

</soap:Body>

</soap:Envelope>

2. Criando WebService

Vamos criar um simples WebService para acessarmos via AJAX + SOAP. Não vou descrever todos o processo de criação de WebServices aqui, pois já o fiz no artigo “Acesso Assíncrono a WebServices na plataforma .NET – Parte II”.

2.1. Criando métodos no WebService

Vamos criar um método chamado Somar que retorna uma string no formato XMLSOAP, afim de exemplificar o Acesso Assíncrono. Segue o código da classe:

using System;

using System.Web;

using System.Collections;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Xml;

/// <summary>

/// Summary description for WebServiceArtigo

/// </summary>

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class WebServiceArtigo : System.Web.Services.WebService

{

public WebServiceArtigo()

{

//Uncomment the following line if using designed components

//InitializeComponent();

}

[WebMethod]

public string HelloWorld()

{

return "Hello World";

}

[WebMethod]

public int Somar(int[] p_arrParametros)

{

return p_arrParametros[0] + p_arrParametros[1];

}

}

2.2. Como conhecer o modelo do XMLSOAP para request e response?

Existe uma forma para se saber como consumir, no caso, o método Somar do WebService criado anteriormente, basta acessar a interface do mesmo. Para isso digite o endereço local do WebService no navegador (http://localhost:1689/WebSiteArtigo/WebServiceArtigo.asmx).

A figura abaixo mostra a interface de acesso do WebService criado anteriormente:

Na parte superior da interface, existe um link com o nome do seu método (Somar). Se clicarmos lá, abrir-se-á uma nova página com os modelos de consumo do método via SOAP 1.1, SOAP 1.2 e via HTTP POST. No nosso exemplo, utilizaremos apenas o modelo de consumo via SOAP 1.1.

É importante nos atentarmos para os cabeçalhos SOAPAction e Content-Type, pois os utilizaremos para realizar a requisição SOAP.

A figura abaixo representa a interface que contém os modelos de consumo dos métodos do nosso WebService:

Agora nós já sabemos qual é o modelo do XMLSOAP de envio e retorno do método Somar.

3. JavaScript para realizar o Acesso Assíncrono

Agora colocaremos o código JavaScript utilizado para consumir o método Somar do nosso WebService. Segue o código:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head id="Head1" runat="server">

<title>Untitled Page</title>

<script type="text/javascript">

var NMHOST = "localhost:1689";

var URLWEBSERVICE = "http://" + NMHOST +

"/WebSiteArtigo/WebServiceArtigo.asmx";

var objXMLHttpRequest;

function NovoXMLHttpRequest()

{

if(window.XMLHttpRequest) // Mozilla, Safari...

{

objXMLHttpRequest = new XMLHttpRequest();

}

else if(window.ActiveXObject) // IE

{

try

{

objXMLHttpRequest = new

ActiveXObject("Msxml2.XMLHTTP");

}

catch(e)

{

try

{

objXMLHttpRequest = new

ActiveXObject("Microsoft.XMLHTTP");

}

catch(e){}

}

}

}

function Somar()

{

NovoXMLHttpRequest();

objXMLHttpRequest.onreadystatechange = ProcessarResposta;

objXMLHttpRequest.open("POST", URLWEBSERVICE, true);

objXMLHttpRequest.setRequestHeader("SOAPAction",

"http://tempuri.org/Somar");

objXMLHttpRequest.setRequestHeader("Content-Type",

"text/xml; charset=utf-8");

objXMLHttpRequest.send(ValoresEnvio());

}

function ProcessarResposta()

{

if(objXMLHttpRequest.readyState == 4)

{

if(objXMLHttpRequest.status == 200)

{

var XMLDoc = objXMLHttpRequest.responseXML;

document.getElementById("lblResultado").innerHTML =

XMLDoc.getElementsByTagName("SomarResult")[0].

childNodes[0].nodeValue;

}

}

}

function ValoresEnvio()

{

var arrParametros = new Array();

arrParametros[0] = document.getElementById(

"txtValor1").value;

arrParametros[1] = document.getElementById(

"txtValor2").value;

return "<?xml version="1.0" encoding="utf-8"?>" +

"<soap:Envelope " +

"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" " +

"xmlns:xsd="http://www.w3.org/2001/XMLSchema" " +

"xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">"

+

"<soap:Body>" +

"<Somar xmlns="http://tempuri.org/">" +

"<p_arrParametros>" +

"<int>" + arrParametros[0] + "</int>" +

"<int>" + arrParametros[1] + "</int>" +

"</p_arrParametros>" +

"</Somar>" +

"</soap:Body>" +

"</soap:Envelope>";

}

function RegistrarScript()

{

document.getElementById("btnSomar").onclick = new

Function("Somar();");

}

</script>

</head>

<body onload="RegistrarScript();">

<form id="form1" runat="server">

<div>

<asp:TextBox ID="txtValor1" runat="server"></asp:TextBox>

<asp:TextBox ID="txtValor2" runat="server"></asp:TextBox>

<input id="btnSomar" type="button" value="Somar" /><br />

<asp:Label ID="lblTexto" runat="server"

Text="Resultado:"></asp:Label>

<asp:Label ID="lblResultado" runat="server"></asp:Label></div>

</form>

</body>

</html>

O método JavaScript a ser chamado no nosso Acesso Assincrono é o Somar, que é vinculado ao botão btnSomar através do método RegistrarScript que por sua vez é chamado no evento onload da tag body, conforme mostrado no código acima.

Obs: É importante enfatizar que no Acesso Assíncrono com SOAP, o método setRequestHeader do objeto XMLHttpRequest dever ser setado com pelo menos dois cabeçalhos http: SOAPAction e Content-Type. Essas informações podem ser recuperadas da interface do WebService.

Abaixo temos a representação gráfica da interface do nosso exemplo:

4. Finalizando

Neste artigo abordamos a construção de um exemplo prático passo-a-passo de Acesso Assíncrono com SOAP.

Fica um desafio para vocês (leitores): consumir o método HelloWorld com AJAX + SOAP do WebService criado neste artigo. Na verdade é uma “tarefa de casa” (risos).

Espero ter contribuído!

Até o próximo!

Diego Gazotto Dezembro
Diego Gazotto Dezembro

Diego Gazotto Dezembro - Trabalha com programação para web há dois anos. É graduando em Processamento de Dados pela FATEC – TQR. Atua como desenvolvedor na plataforma .NET na POLITEC – TQR (www.politec.com.br). Verdadeiro entusiasta em arquitetura de sistemas web.