WCF, JSON e Script Tag dinâmico

Pessoal, de volta aos posts técnicos, hoje vamos falar um pouco de requisições assíncronas utilizando Javascript (claro), ASP.NET Webforms / MVC, WCF e JSON (REST / RESTful).

Aqui no meu trabalho, por algumas razões, temos dois servidores físicos como servidor de aplicação (falando de IIS), sendo um para aplicações ASP.NET e outro com aplicações (legados) em ASP clássico.

Como todos os novos Softwares e Serviços que estamos fazendo há um tempo são desenvolvidos utilizando .NET, não temos problemas para fazer requisições assíncronas entre os serviços de aplicações. Mas, certo dia, tinhamos a necessidade de consumir esses serviços novos (WCF) no ASP clássico, em outro domínio. Resumindo: “Acesso negado”.

Então, como fazer para resolver esse problema? Um Proxy? Pode ser, mas nesse caso, precisariamos fazer o proxy em ASP, pois no servidor antigo não está com o .NET Framework instalado. Então essa opção, sozinha, foi descartada.

Pra solucionar esse problema, recorremos ao uso da Tag HTML Script e também de um Proxy. Vamos ver como funciona:

Diagrama de Sequencia

Proxy - Solution Explorer

Vamos aos códigos (de trás pra frente):

Código do “Qualquer Serviço”: apenas um serviço WCF retornando uma lista da classe Pessoa em formato JSON (Get). No projeto disponibilizado, esta classe está em uma biblioteca de classe a parte, simulando qualquer serviço já existente. Apesar da hospedagem deste serviço, no projeto, ter ficado dentro da aplicação ASP.NET MVC (pasta: Services).

Código: IServico.cs

using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;

[ServiceContract]
public interface IServico
{
    [OperationContract]
    [WebGet(ResponseFormat=WebMessageFormat.Json)]
    List<Pessoa> MetodoQualquerJson();
}

Código: Servico.cs

using System.Collections.Generic;
using System.Runtime.Serialization;

public class Servico : IServico
{
    public List<Pessoa> MetodoQualquerJson()
    {
        return new List<Pessoa>()
        {
            new Pessoa() { Nome = "Bruno Kenj", Idade = 25 },
            new Pessoa() { Nome = "Rodrigo Kono", Idade = 26 },
            new Pessoa() { Nome = "Evilázaro Alves", Idade = 27 },
        };
    }
}

[DataContract]
public class Pessoa
{
    [DataMember]
    public string Nome { get; set; }
    [DataMember]
    public int Idade { get; set; }
}



Código do Proxy: mais um serviço WCF retornando Javascript. Este serviço está no projeto ASP.NET MVC (pasta: Services e Services/Interfaces).

Código: Proxy.svc.cs

using System.Text;
using System.IO;

using System.ServiceModel.Web;
using System.Net;

namespace Proxy.Services
{
    public class Proxy : IProxy
    {
        public Stream GetJSON(string nomeObjeto, string url)
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript";

            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);

            string content;

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = WebRequestMethods.Http.Get;
            WebResponse response = request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());
            content = reader.ReadToEnd();
            response.Close();

            writer.Write(string.Format("var {0} = eval({1});", nomeObjeto, content));
            writer.Flush();
            stream.Position = 0;

            return stream;
        }
    }
}



Código da View: Apresentaçãlo HTML que vai fazer a requisição via tag Script.

Código: Index.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

    <script type="text/javascript" src="Services/Proxy.svc/GetJSON?nomeObjeto=objJson&url=http://localhost:8879/Services/ServicoQualquer.svc/MetodoQualquerJson" language="JavaScript"></script>

    <script type="text/javascript">

        for (name in objJson)
        {
            if (objJson.hasOwnProperty(name))
            {
                alert("Nome: " + objJson[name].Nome + " | Idade: " + objJson[name].Idade);
            }
        }

    </script>

</asp:Content>



Caso NÃO precise de utilizar a tag Script mas apenas um Proxy, você poderá utilizar a função getJSON do JQuery:

    <script type="text/javascript">

        $(document).ready(function() {
            $.getJSON(
                "http://localhost:8879/Services/ServicoQualquer.svc/MetodoQualquerJson",
                function(data) {
                    $.each(data, function(i, item) {
                        alert("Nome: " + item.Nome + " | Idade: " + item.Idade);
                    });
                });
        });

    </script>



E pra finalizar a solução, deixo aqui a parte do Web.Config para retornarmos REST via WCF:

Código: Web.config (somente a parte do WCF)

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="REST">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="ServicoQualquer">
        <endpoint address="" binding="webHttpBinding" contract="IServico" behaviorConfiguration="REST" />
      </service>
      <service name="Proxy.Services.Proxy">
        <endpoint address="" binding="webHttpBinding" contract="Proxy.Services.IProxy" behaviorConfiguration="REST" />
      </service>
    </services>
  </system.serviceModel>

Pronto!

Proxy - Resultado



Download da Solução

Clique aqui para baixar

Atenção: Ao fazer o download da solução, ficar atento a porta da URL que estou utilizado (localhost:8879), pois eu rodei a aplicação pelo próprio Visual Studio. Você precisa mudar essa porta para testar no seu ambiente (ou até mesmo remover).

Atenção: O projeto ASP.NET MVC está rodando na versão 2 Preview 2. É necessário a instalação do ASP.NET MVC 2 Preview 2.

O próprio ASP.NET MVC já tem o JsonResult como retorno do Action. Se alguém tiver alguma dúvida ou sugestão, por favor, entre em contato: contato@brunokenj.net.

Comentário fechado.