O que é um Web Service
Web Service é uma solução utilizada na integração de sistemas e na comunicação entre aplicações diferentes. Com ele existe a possibilidade de fazer a comunicação de uma aplicação legada ou aplicações em plataformas diferentes. Cada aplicação pode ter a sua própria “linguagem”, que é traduzida para uma linguagem universal, um formato intermediário como XML, Json, etc. Com isso ele facilita a comunicação entre as aplicações através da Internet.
Tecnologia usada
Um Web Service utiliza os padrões XML e SOAP para comunicação. O transporte dos dados é realizado normalmente via protocolo HTTP ou HTTPS (para conexões seguras). Os dados são transferidos no formato XML, encapsulados pelo protocolo SOAP. Também é bastante comum usar o protocolo REST ( Representational transfer protocol), para transferir o estado do dado para a aplicação.
O que é o SOAP?
O SOAP ou Simple Object Access Protocol é o protocolo de comunicação do Web Service, ele é um protocolo que funciona sobre o HTTP. Em vez de usar HTTP para pedir uma página HTML para ser visualizada num browser, o SOAP envia uma mensagem de XML através do pedido HTTP e recebe uma resposta. Para assegurar corretamente a transmissão da mensagem de XML, o servidor de HTTP, tais como Apache ou IIS (Microsoft Internet Information Server), recebe mensagens SOAP e deve validar e compreender o formato do documento XML definido na especificação SOAP v1.1.
O WSDL
O WSDL ou Web Services Description Language é um padrão baseado em XML que serve para descrever os Web Service, nele contém os métodos públicos do Web Service, ele funciona como uma “TypeLibrary” dos serviços.
Como consumir um Web Service
Bem agora deixemos de teoria e vamos para a parte prática, para consumir um Web Service no .NET não tem muito mistério, vamos começar criando um novo projeto ASP.NET MVC no Visual Studio
Vamos selecionar MVC
E no Change Authentication, vamos deixar No Autentication
Com o projeto criado agora vamos fazer a referência ao Web Service, no exemplo vamos usar o serviço de consulta de cep dos correios (https://apps.correios.com.br/SigepMasterJPA/AtendeClienteService/AtendeCliente?wsdl), para fazer isso vamos clicar com o botão direito do mouse em “References” e selecionar “Add Service Reference”
Na janela que vai abrir vamos digitar o endereço em “Address” e depois clicar em “Go”
Após fazer esse processo podemos ver que é encontrado o serviço. Nesse passo também renomeamos o nosso “Namespace” para Correios.
Pronto, com apenas isso já podemos fazer consultas no serviço dos correios. Lembrando que essa url disponibiliza vários serviços, mais só vamos utilizar o de consulta de cep.
Para utilizar a consulta é muito simples, basta utilizar o código abaixo:
var correios = new Correios.AtendeClienteClient(); var consulta = correios.consultaCEP(“70390-700”);
Veja como é simples, só de olhar podemos tirar a seguinte conclusão, que estamos utilizando classes e métodos que estão em outra aplicação.
É basicamente isso, instanciar uma classe e utilizar um método que nos vai retornar um objeto. No caso acima instanciamos a classe AtendeClienteClient e vamos usar o método consultaCEP, no caso de ter dúvida quais as classes e métodos que o Web Service te disponibiliza você pode consultar os mesmo pelo “Object Browser” abrindo a pasta “Service References” e clicar em Correios que foi o NameSpace que criamos.
Podemos ver no “Object Browser” o que o serviço tem de disponível. Podemos ver na imagem o que nós utilizamos:
Bem com o conceito vamos partir para a implementação da nossa aplicação, primeiro vamos criar 2 classe para atender nosso modelo, uma vai ser a Cep e a outra Endereço, abaixo vemos o código das classes:
public class Cep { [Required] [MaxLength(9, ErrorMessage = "Cep tem que ser digitado no formato 70000-000")] [MinLength(9, ErrorMessage ="Cep tem que ser digitado no formato 70000-000")] public string Codigo { get; set; } } public class Endereco { public string Descricao { get; set; } public string Complemento { get; set; } public string Bairro { get; set; } public string Cidade { get; set; } public string UF { get; set; } }
Na nossa view vamos ter um textbox para informar o cep o mesmo vai dar um post para a controler passando o nosso cep:
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { <div class="form-group"> <div class="input-group"> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.TextBoxFor(m => m.Codigo, new { @class = "form-control" }) <span class="input-group-btn"> <input type="submit" value="Buscar" class="btn btn-default" /> </span> </div> </div> <div> @Html.ValidationMessageFor(m => m.Codigo, "", new { @class = "text-danger" }) </div> }
Na controller vamos receber o objeto e fazer a consulta no Web Service, com o retorno vamos alimentar o objeto Endereco para apresentar na view, conforme o código abaixo:
[HttpPost] public ActionResult Index(Models.Cep cep) { if (!ModelState.IsValid) { return View(cep); } using (var correios = new Correios.AtendeClienteClient()) { var consulta = correios.consultaCEP(cep.Codigo.Replace("-", "")); if (consulta != null) { ViewBag.Endereco = new Models.Endereco() { Descricao = consulta.end, Complemento = consulta.complemento, Bairro = consulta.bairro, Cidade = consulta.cidade, UF = consulta.uf }; } } return View(cep); }
O retorno vai ser exibido na mesma view que fizemos a consulta, utilizando o seguinte código:
@{ if (ViewBag.Endereco != null) { @ViewBag.Endereco.Descricao @ViewBag.Endereco.Complemento @ViewBag.Endereco.Bairro @ViewBag.Endereco.Cidade @ViewBag.Endereco.UF } }
Bem no resultado final temos o seguinte resultado:
Bem simples o exemplo mais podemos ter uma noção de como consumir um Web Service, abaixo vou deixar o fonte disponível no github para poderem ver como ele funciona.
Até a próxima.
Exemplo:
https://github.com/tborgesvieira/Web-Service-Client
Referências:
https://pt.wikipedia.org/wiki/Web_service
Certinho! Vlwww Thiagão! Acabei de fazer aqui 😀
Vlw Régner 😀
E quando o Webservice exigir usuário e senha?
Vai depender da forma de como está implementado, geralmente vai passar isso em algum objeto.
Já vi algumas situações em que se passa o usuário e a senha em claro mesmo, outros casos o objeto da senha vai em base64 e também em alguns casos se utiliza certificado digital, mandando a mensagem assinada. Mais vai depender de como foi implementado o serviço.
No meu caso , na Request usando o SoapUI eu tenho como exemplo passando o usuário e senha pelo header, porém na ferramenta que utilizamos na empresa ( maker studio, da softwell) o sistema gera o header e só me deixar passar o body, como passar essa autenticação ( usuário e senha ) dentro do body ?
desde já agradeço
Pelo que eu to entendendo você ta consumindo um web service de alguém, no caso tem que ver como são os parâmetros de autenticação do web service que você está tentando se conectar. Alguns passam no body mesmo, eles criam um objeto para você passar o usuário e senha, alguns passam a senha em claro, outro pedem para gerar um hash, mais isso tudo vai depender de onde você está tentando conectar. Deve existir alguma documentação explicativa de como fazer o acesso.
E pra usar um CRUD em cima desse webservice como faria, no caso das views adicionar uma view de delete, editar e detalhes, e fazer o post pra criar algo pro webservice do projeto c# para o webservice em Java, como seria esses codigos? Como ficariam?
Olá Rhay, para operações de CRUD você vai ter um método para cada um dos eventos, e em suas views fariam as requisições de acordo com a operação que vai ser realizada.
Olá Thiago,
Parabéns pelo conteudo, muito bom.
Estou tentando implantar em um sistema que criei de “ORDEM DE SERVIÇO” a emissão da NFe,
Consegui gerar o xml, validar e assinar agora estou lutando para consumir o WEB SERVICE da SEFAZ para enviar as notas fiscais e não tenho noção de como fazer isto, sou iniciante em C#.
Seguindo seu post consegui implantar os WEB Services mas não tenho a minima noção de como chama-los para enviar tais arquivos, teria algum material sobre o assunto?
No aguardo, desde de já agradeço.
Parabéns pelo trabalho.
Cara, aqui eu trabalho com isso, eu crio dinamicamente passando o wsdl do servidor que vou usar. Existe um projeto em c# que dá para usar como referência, ele é open-source: http://www.unimake.com.br/uninfe/
Olá Thiago, obrigado pela resposta.
Vou analisar sua dica de site.
Pesquisando sobre tal assunto, cheguei neste código:
private void ConsumirWeb()
{
string caminho = (AppDomain.CurrentDomain.BaseDirectory + “\\NotaFiscal.XML”);
//cabeçalho do ws
string wsCabecMsg = “1.10”;
X509Certificate2 CERT = default(X509Certificate2);
CERT = BuscaNome(x509Cert);
//rotina para buscar o certificado usado
System.Xml.XmlNode strRetorno;
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(caminho);
//Carrega o arquivo XML
RecepcaoEvento.RecepcaoEvento wsMsg;
wsMsg = new RecepcaoEvento.RecepcaoEvento();
wsMsg.Timeout = 100000;
wsMsg.ClientCertificates.Add(CERT);
//adiciona o certificado na conexão
wsMsg.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap12;
caminho = xmldoc.OuterXml;
//envia seu arquivo xml para o webservice e retorna o resultado
strRetorno = wsMsg.nfeRecepcaoEvento(xmldoc.DocumentElement);
//strRetorno = wsMsg.nfeRecepcaoLote(wsCabecMsg, dados) ‘envia seu arquivo xml para o webservice e retorna o resultado
Observe que a variavel “strRetorno” coloquei duas vezes, a primeira foi adaptada para que o codigo nao apresentasse erro. Mas creio que a forma correta é a útlima linha, porem se usar ela o método “nfeRecepcaoLote” consta como invalido, pois não pertence aos ws que importei.
Caso possa da uma olhada para ver se estou no caminho certo ficarei grato.
Mais uma vez, obrigado.
Eu estou fazendo isso mesmo, tá bem parecido com o que tenho aqui.
Então Thiago, vamos lá:
/envia seu arquivo xml para o webservice e retorna o resultado
strRetorno = wsMsg.nfeRecepcaoEvento(xmldoc.DocumentElement);
strRetorno = wsMsg.nfeRecepcaoLote(wsCabecMsg, dados) ‘envia seu arquivo xml para o webservice e retorna
Nos modelos que consegui na net usava “nfeRecepcaoLote”, mas parece que hoje a forma de enviar é o “nfeRecepcaoEvento” é isto mesmo?
Porque é justamente aí que ta pegando, se uso o primeiro (nfeRecepcaoLote) dá erro dizendo que não faz parte do projeto, se uso a segunda opção (nfeRecepcaoEvento) me diz que o metodo não suporta entrada de dois paramentros que seria (wsCabecMsg, dados) o cabealho + o xml assinado.
Teria como voce me dá uma luz sobre o assunto. Qual das destas opções você usa nos seus projetos NFE?
Mais uma vez muito obrigado pela presteza e atenção nas respostas.
Bom dia!
Bom dia Thiago.
Por acaso vc sabe como fazer um web service c# responder no padrão ISO-0-8859-1 ?
Coloca assim no construtor do seu webservice:
this.Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding(“ISO-8859-1”);
Não deu certo, vou tentar ser mais claro com relação ao meu problema. Montei um Web Service que retorna uma classe gerada a partir de um WSDL. Porém a empresa que vai consumir este web service solicitou que o encoding do cabeçalho HTTP dever ser ISO-8859-1.
Segue exemplo abaixo:
[WebService(Namespace = “http://unimedwsd.com.br/webservices”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class RespostaAuditoriaHomologacao : WebService
{
[WebMethod(Description = “Resposta de auditoria”)]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute(“”, Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute(“confirmacaoWS”, Namespace = “http://ptu.unimed.coop.br/schemas/V70_00”)]
public confirmacaoWS RespostaAuditoriaOperation([System.Xml.Serialization.XmlElementAttribute(Namespace = “http://ptu.unimed.coop.br/schemas/V70_00”)] respostaAuditoriaWS respostaAuditoriaWS)
{
confirmacaoWS confirmacaoWS = new confirmacaoWS();
confirmacaoWS.cabecalhoTransacao = new ct_cabecalhoTransacao();
confirmacaoWS.confirmacao = new ct_confirmacao();
confirmacaoWS.cabecalhoTransacao.codigoTransacao = st_cdTrans.Item00309;
confirmacaoWS.cabecalhoTransacao.codigoUnimedOrigemBeneficiario = CreateWebRequest(“970”);
confirmacaoWS.cabecalhoTransacao.codigoUnimedPrestadora = CreateWebRequest(“72”);
confirmacaoWS.cabecalhoTransacao.tipoCliente = st_tpCliente.UNIMED;
confirmacaoWS.confirmacao.identificador = st_tpIdentificadorConfirmacao.Item1;
confirmacaoWS.confirmacao.numeroTransacaoOrigemBeneficiario = CreateWebRequest(“12345”);
confirmacaoWS.confirmacao.numeroTransacaoPrestadora = CreateWebRequest(“54321”);
confirmacaoWS.confirmacao.numeroVersaoPTU = CreateWebRequest(“070”);
confirmacaoWS.hash = CreateWebRequest(“654654654654654654”);
return confirmacaoWS;
}
Precisa fazer este método retornar com ISO-8859-1.
Me manda um email com o WSDL para eu dar uma olhada: tborgesvieira@gmail.com
Enviado
Olá Thiago,
O link do seu github não consta o código fonte, poderia me enviar por gentileza…..
Abraço,
Mário
Opa, o link está incorreto, já ajustei
github.com/tborgesvieira/Web-Service-Client
Oi Mestre Thiago, tudo bem? EM primeiro lugar (antes de solicitar imensamente sua ajuda), gostaria de parabenizar seu conteúdo, sempre didático, como sua disposição em nos ajudar. Bom vamos lá… Eu sou iniciando na plataforma .Net ASP.CORE. Peguei o exemplo do template do RazorMoviePage e estou modificando para um app de uso próprio, algo útil, onde irei cadastrar as minhas ‘muambas’ da Geabest, AliExpress, Ebay e por aí vai. Para tal irei ter uma funcionalidade de checar o status dos correios. Bom, eu já implementei tudo mas sempre que vou consumir dá um erro de assembly, gera uma exception, antes era no System.Model e agora é no Systema.Web (Exceção gerada: ‘System.IO.FileNotFoundException’ em MyMuambator.dll
Ocorreu uma exceção do tipo “System.IO.FileNotFoundException” em MyMuambator.dll, mas ela não foi manipulada no código do usuário
Could not load file or assembly ‘System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’. O sistema não pode encontrar o arquivo especificado.). Já tentei de tudo! Se puder me ajudar te envio o projeto todo zipado. Te enviei um invite no Skype. Desde já agradeço amigo. 🙂
Olá Marcelo, se puder me enviar por email tborgesvieira@gmail.com, assim que me sobrar um tempo dou uma olhada para ver o que pode está acontecendo.
Show de bola! Mando sim… Criei um windows forms para isolar o problema do assembly e ao menos tentar sucesso na chamada da referência ao WS de rastreamento mas ainda sem sucesso também. Sem bug na compilação mas o método não retorna nada…
Thiago, como os projetos eram grandes por email não permitiu. Compartilhei uma pasta no meu gdrive. Abcs. Me avise se conseguir acessar. Abcs.
Bom dia Thiago,
Li e Apliquei seu post, gostei muito.
Parabéns.
Estou com um problema ao acessar um WSDL.
Que passa login e senha e talvez você tenha alguma sugestão.
login
senha
id
Erro ao tentar conectar com o serviço usando metodo *post* passando credenciais como visto acima.
Erro ocorreu no visual studio
Método: HttpWebRequest GetResponse
Erro: The remote server returned an error: (405) Method Not Allowed.
Method Not Allowed
Response = {System.Net.HttpWebResponse}
Eu não possuo acesso as configurações do serviço pois são de terceiro.
Fiz o acesso usando SoapUi e funcionou perfeitamente.
Usei o serviço dos Correios mudando apenas o endereço do WSDL que você passou aqui e o envio dos parâmetros.
Passei o cep e retornou endereço como esperado.
Mas no caso do WSDL terceiro ele aceita o *GET* mas dá o erro 405 quando eu envio *POST*.
Eu assumiria não ser possível acessar o serviço se o SoapUi não acessasse RS
Será que você ou alguém que lê este comentário tem alguma dica, instrução ou sugestão valida?
Mais no caso ele está retornando 405 e não 403, 405 é que o método não é aceito pelo servidor, no caso de não autorizado seria o 403
Vi algumas pessoas que preferem criar essas referencias de modo manual. Você acha que essa seria uma forma correta? E se sim, como eu poderia fazer isso nesse web service dos correios que você usou de exemplo? Desde já, obrigado.
Olá Leonardo, sim realmente tem como você fazer isso que você mencionou, mas só vejo a necessidade de utilizar dessa forma quando você deseja isolar ou tem vários endpoints que utilizam o mesmo wsdl. Um cenário que utilizo assim é na Nota Fiscal Eletrônica.
Assim que possível eu monto um exemplo de como faço nesses casos.