none
Retornar XML RRS feed

  • Pergunta

  • Olá.

    Como eu faço no WCF para retornar um XML? Vi que existe o Serialization mas não compreendi sua funcionalidade. Quando eu desenvolvi anteriomente um WS, eu tinha um método que retornava uma string, porém eu pegada um DataSet e utilizada o método GetXml e a aplicação que acesso o WS conseguia utilizar, é possível fazer o mesmo com o WCF ou existe outra forma?

    Obrigado.
    Marcos Aguiar Jr - Brazil
    quarta-feira, 17 de junho de 2009 20:54

Respostas

  • Boas Marcos,

    A comunicação entre as partes sempre é realizada em XML, seguindo o protocolo SOAP.

    Quando você publica um serviço, você também disponibiliza o WSDL. Os metadados têm um papel importante dentro do WCF e de qualquer web service. Regidos por padrões mundialmente conhecidos, como WSDL (Web Services Description Language) ou o WS-Policy/WS-MetadataExchange, utilizam a linguagem XML/XSD para descrever um serviço, especificando suas operações e tipos de dados (que no seu caso é a classe Associado) que ele suporta.

    Felizmente, ao referenciar o serviço no cliente (utilizando o Visual Studio ou o svcutil.exe), ele extrairá todas as informações do WSDL e montará a classe do lado do cliente. A finalidade de você ter um framework de serviços, é justamente ele encapsular toda a parte complexa, que é lidar com o XML. Em outras plataformas, como JAVA, acredito que também exista algo semelhante.

    Caso ele não fazer a criação do proxy, então ai sim você precisaria lidar diretamente com o XML, criando os envelopes SOAP, serializando as informações. Mas, como disse, isso é uma tarefa um pouco mais complexa do que trabalhar somente com os tipos. Ainda há algumas outras alternativas para criar essas mensagens, como os Message Contracts, mas eles tem um foco diferente.
    http://www.israelaece.com
    sexta-feira, 19 de junho de 2009 12:43
    Moderador

Todas as Respostas

  • Boas Marcos,

    Você pode retornar uma string que contém um XML, assim como já fazia anteriormente.

    Essa string fará parte do corpo da mensagem. Se precisar formatar o corpo da mensagem em um formato específico, então você pode dar uma olhada na criação customizada dos Messages Contracts: http://www.israelaece.com/post/WCF-MessageContracts.aspx.

    Somente tome cuidado para retornar Datasets: http://www.israelaece.com/post/Utilizando-Datasets-em-servicos.aspx.
    http://www.israelaece.com
    quinta-feira, 18 de junho de 2009 11:06
    Moderador
  • Olá Israel.

    Li seu artigo sobre MessageContracts e fiz download do projeto de exemplo. Eu vi que no arquivo program.cs do projeto client você está passando um objeto para o WCF certo? Se for isso, dessa forma não posso ter problema caso minha aplicação que irá chamar o WCF esteja em outra platarforma de desenvolvimento que não seja C# ou VB.NET?


    Sobre seu artigo de DataSets, entendi, veja o exemplo abaixo e me diga se dessa forma é correta ou posso ter problemas, estou usando um projeto WCF Library.

    Na Interface
        [ServiceContract()]
        public interface ICalculatorService
        {
            [OperationContract]
            string Add(decimal n1, decimal n2);
        }
    na Class

        public class CalculatorService : ICalculatorService
        {
            public string Add(decimal n1, decimal n2) 
            {
                DataSet dsAdd = new DataSet("Dado");
                
                DataTable dtResult = new DataTable("Linha");
                dtResult.Columns.Add("VALOR", typeof(Int64));
    
                DataRow dr = dtResult.NewRow();
                dr["VALOR"] = n1 + n2;
    
                // Adicionando a linha a tabela de totais
                dtResult.Rows.Add(dr);
    
                // Adicionando a tabela ao dataset
                dsAdd.Tables.Add(dtResult);
    
                return dsAdd.GetXml();
    
            }
        }
    Se puder ajudar novamente, fico agradecido.

    Obrigado.
    Marcos Aguiar Jr - Brazil
    quinta-feira, 18 de junho de 2009 11:47
  • Boas Marcos,

    A idéia da criação de Message Contracts, é justamente permitir ao WCF criar uma mensagem que segue o formato de um serviço específico, ou seja, quando a formatação padrão do WCF não atende o formato da mensagem esperada pelo outro lado (seja .NET ou não).

    O código acima deve funcionar, mas para que precisa disso? Não poderia retornar um decimal?
    http://www.israelaece.com
    quinta-feira, 18 de junho de 2009 12:02
    Moderador
  • Israel.

    Então esse código que coloquei é só um exemplo, na verdade a questão seria e se eu tivesse que retornar um conjunto de dados? Por exemplo, nome, endereço, CEP de vários clientes? Eu deveria retornar um array? E ao retornar um array o WCF já o enviaria como XML?

    Obrigado.


    Marcos Aguiar Jr - Brazil
    quinta-feira, 18 de junho de 2009 12:07
  • Boas Marcos,

    Sim, o ideal é sempre recorrer a um array, com objetos tipados que representarão a tua regra/modelo.

    Nós sempre manipulamos os objetos, coleções e arrays, mas ao serializar isso, ele irá utilizar XML. O que trafegará entre o cliente/serviço ou entre o serviço/cliente sempre será em formato XML.

    Ao referenciar o serviço em um cliente, o WCF (ou qualquer outro framework de serviço) utiliza o WSDL para criar o proxy. A criação e leitura do XML é transparente, ou seja, não preciso conhecer esses detalhes para fazer com que o serviço funcione. O WCF se encarregará de transformar o XML em objetos.
    http://www.israelaece.com
    quinta-feira, 18 de junho de 2009 12:58
    Moderador
  • Israel.

    Por exemplo, imagina que eu tenho o seguinte código
    [OperationContract]
            string SolicitarEmprestimo(Associado associado);
    
    
    [DataContract]
        public class Associado
        {
            string numeroMatricula = "";
            decimal valorEmprestimo = 0;
            decimal qtdeParcela = 0;
            decimal taxaJuros = 0;
            decimal linhaCredito = 0;
    
            [DataMember]
            public string NumeroMatricula
            {
                get { return numeroMatricula; }
                set { numeroMatricula = value; }
            }
    
            [DataMember]
            public decimal ValorEmprestimo
            {
                get { return valorEmprestimo; }
                set { valorEmprestimo = value; }
            }
    
            [DataMember]
            public decimal QtdeParcela
            {
                get { return qtdeParcela; }
                set { qtdeParcela = value; }
            }
    
            [DataMember]
            public decimal TaxaJuros
            {
                get { return taxaJuros; }
                set { taxaJuros = value; }
            }
    
            [DataMember]
            public decimal LinhaCredito
            {
                get { return linhaCredito; }
                set { linhaCredito = value; }
            }
        }
    
    
    Agora eu quero que a minha aplicação client chame o método SolicitarEmprestimo, como devo proceder? Fiz esse metódo retornar um array de string, como faço para o client pegar esse valor em XML?

    Obrigado.
    Marcos Aguiar Jr - Brazil
    quinta-feira, 18 de junho de 2009 20:40
  • Boas Marcos,

    Mas não consigo entender porque quer retornar XML a partir do teu método. Você realmente precisa disso?

    Se quiser retornar um array, então basta definir isso no seu contrato:

    [OperationContract]
    string[] RecuperarDados(Associado a);

    É importante dizer que o WCF trabalha no formato RPC, ou seja, ao referenciar o serviço no cliente, ele irá ler o WSDL e criará um proxy com um "espelho" dos métodos expostos pelo contrato que você publicou no serviço. Esse proxy nada mais é do que uma classe local, que você invocará os métodos dela como se fosse uma classe normal. Em tempo de execução, ela irá enviar a mensagem para o respectivo serviço, o mesmo irá executar devolver o resultado para o cliente e ele fará o que desejar.

    Desculpe-me se não consegui perceber o seu problema.
    http://www.israelaece.com
    sexta-feira, 19 de junho de 2009 01:43
    Moderador
  • Olá Israel.

    Acho que não estou sendo claro, me desculpe.

    Pegando o código que você viu na mensagem acima, peguei um projeto Web Site e adicionei o WCF a ele. Nesse Web Site fiz o seguinte:

            Service1Client ws = new Service1Client();
    
            Associado associado = new Associado();
            associado.NumeroMatricula = "123";
            associado.ValorEmprestimo = Convert.ToDecimal(this.txtValor.Text);
            associado.QtdeParcela = Convert.ToDecimal(this.txtQtdeParcela.Text);
            associado.TaxaJuros = 1;
            associado.LinhaCredito = 1;
    
            this.lblTexto.Text = ws.SolicitarEmprestimo(associado);
    Funcionou perfeitamente, as dúvidas são:

    O método SolicitarEmprestimo retorna string, no processo interno na verdade o que está sendo trocando entre a aplicação Web Site eo WCF é um XML? O método SolicitarEmprestimo exige como parâmetro um objeto Associado, no .NET ao referenciar o WCF a class Associado já ficou disponível, mas se fosse outra plataforma que acessa-se o WCF? conseguiria passar um objeto Associado também?

    Obrigado.
    Marcos Aguiar Jr - Brazil
    sexta-feira, 19 de junho de 2009 12:11
  • Boas Marcos,

    A comunicação entre as partes sempre é realizada em XML, seguindo o protocolo SOAP.

    Quando você publica um serviço, você também disponibiliza o WSDL. Os metadados têm um papel importante dentro do WCF e de qualquer web service. Regidos por padrões mundialmente conhecidos, como WSDL (Web Services Description Language) ou o WS-Policy/WS-MetadataExchange, utilizam a linguagem XML/XSD para descrever um serviço, especificando suas operações e tipos de dados (que no seu caso é a classe Associado) que ele suporta.

    Felizmente, ao referenciar o serviço no cliente (utilizando o Visual Studio ou o svcutil.exe), ele extrairá todas as informações do WSDL e montará a classe do lado do cliente. A finalidade de você ter um framework de serviços, é justamente ele encapsular toda a parte complexa, que é lidar com o XML. Em outras plataformas, como JAVA, acredito que também exista algo semelhante.

    Caso ele não fazer a criação do proxy, então ai sim você precisaria lidar diretamente com o XML, criando os envelopes SOAP, serializando as informações. Mas, como disse, isso é uma tarefa um pouco mais complexa do que trabalhar somente com os tipos. Ainda há algumas outras alternativas para criar essas mensagens, como os Message Contracts, mas eles tem um foco diferente.
    http://www.israelaece.com
    sexta-feira, 19 de junho de 2009 12:43
    Moderador
  • Ola Israel.

    Acho que entendi, vou fazer uns testes para verificar.

    Obrigado pela ajuda e paciência.


    Marcos Aguiar Jr - Brazil
    sexta-feira, 19 de junho de 2009 15:04