<rss version="2.0" xmlns:a10="http://www.w3.org/2005/Atom"><channel><title>Dicas Técnicas BufaloInfo</title><link>http://www.bufaloinfo.com.br/</link><description>Dicas Técnicas Produzidas pela Búfalo Informática</description><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=997</link><title>WebServices : Utilizando parâmetros opcionais com REST no WCF</title><description>&lt;br&gt;O atributo WebGet n&amp;#227;o suporta o uso de par&amp;#226;metros opcionais, ou seja : Se voc&amp;#234; tiver par&amp;#226;metros no seu m&amp;#233;todo que n&amp;#227;o estejam explicitamente indicados no webGet, ele vai supor de forma errada que seriam par&amp;#226;metros para POST e falha - afinal estamos falando de um GET.&lt;br&gt;&lt;br&gt;Ent&amp;#227;o o que acontece se voc&amp;#234; precisar de um par&amp;#226;metro opcional ? Por exemplo :&lt;br&gt;&lt;br&gt;&lt;br&gt;http://meusite.com.br/blogs/listar/?f=rss&lt;br&gt;&lt;br&gt;Onde f=rss &amp;#233; um par&amp;#226;metro opcional de indica&amp;#231;&amp;#227;o do formato que deve ser utilizado na resposta ?&lt;br&gt;&lt;br&gt;Para resolver isso podemos recuperar os par&amp;#226;metros em c&amp;#243;digo, ao inv&amp;#233;s de indica-los como par&amp;#226;metro do m&amp;#233;todo que faz parte do contrato WCF. Veja um exemplo :&lt;br&gt;&lt;br&gt;F = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters.Get(&amp;quot;f&amp;quot;)&lt;br&gt;&lt;br&gt;Simples assim, no c&amp;#243;digo resolvemos o problema dos par&amp;#226;metros opcionais com webGet&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=960</link><title>WebServices : Configurando o Host de uma Classe de Negócio</title><description>&lt;br&gt;O Visual Studio possui um template para cria&amp;#231;&amp;#227;o de um servi&amp;#231;os WCF que s&amp;#227;o &amp;quot;automaticamente&amp;quot; configurados para hospedagem em ambiente web (ou seja, o arquivo .svc j&amp;#225; &amp;#233; criado automaticamente)&lt;br&gt;&lt;br&gt;O problema &amp;#233; que se programarmos nosso servi&amp;#231;o dentro deste projeto teremos pouca versatilidade na utiliza&amp;#231;&amp;#227;o da classe de neg&amp;#243;cio, ela ficar&amp;#225; presa ao projeto web.&lt;br&gt;&lt;br&gt;Assim sendo pode ser prefer&amp;#237;vel programar o servi&amp;#231;o em um projeto class library separado. Depois de haver criado o projeto web WCF Service fa&amp;#231;a o seguinte :&lt;br&gt;&lt;br&gt;1) Crie um projeto de class library&lt;br&gt;&lt;br&gt;2) Adicione a refer&amp;#234;ncia para o System.ServiceModel e System.Runtime.Serialization&lt;br&gt;&lt;br&gt;3) No projeto web, adicione refer&amp;#234;ncia para o projeto class library&lt;br&gt;&lt;br&gt;4) No projeto web, delete os 2 arquivos de c&amp;#243;digo&lt;br&gt;&lt;br&gt;5) Altere o arquivo .svc para se referir a classe do servi&amp;#231;o e retire o atributo codebehind&lt;br&gt;&lt;br&gt;6) Altere o arquivo web.config para se referir a classe e ao contrato do servi&amp;#231;o&lt;br&gt;&lt;br&gt;&lt;br&gt;Pronto ! Sua classe de neg&amp;#243;cio est&amp;#225; isolada em uma class library e o projeto web funciona como host para o servi&amp;#231;o, mas sem limita-lo.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=878</link><title>WebServices : Retornando dataTables em WebServices</title><description>&lt;br&gt;A partir do framework 2.0 o dataSet e as dataTables sofreram algumas pequenas mudan&amp;#231;as. Tais mudan&amp;#231;as fizeram com que retornar uma dataTable a partir de um webService n&amp;#227;o seja algo mais t&amp;#227;o simples como definir o valor de retorno de uma fun&amp;#231;&amp;#227;o.&lt;br&gt;&lt;br&gt;A partir do framework 2.0, se desejarmos retornar uma &amp;#250;nica dataTable, precisamos fazer o seguinte : &lt;br&gt;&lt;br&gt;Primeiramente preencher a dataTable que est&amp;#225; no dataset normalmente&lt;br&gt;Criar uma dataTable desvinculada do dataset - uma nova possibilidade a partir da vers&amp;#227;o 2.0&lt;br&gt;&lt;br&gt;Importar os dados para a nova dataTable desvinculada, o que pode ser feito da seguinte forma :&lt;br&gt;&lt;br&gt;tabelaNova.load(tabelaAntiga.createdatareader())&lt;br&gt;&lt;br&gt;Devolver pelo webService a nova dataTable, desvinculada do dataSet.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=866</link><title>WebServices : WCF com TCP e o endereço de MEX</title><description>&lt;br&gt;Quando criamos um servi&amp;#231;o TCP precisamos de dois endpoints, um endpoint TCP e outro endpoint MEX, isso todos sabem.&lt;br&gt;&lt;br&gt;Mas quando damos endere&amp;#231;o aos endpoints, voc&amp;#234; sabia que o endere&amp;#231;o MEX (que &amp;#233; anexado ao base address, &amp;#243;bvio) &amp;#233; considerado default ?&lt;br&gt;&lt;br&gt;Se voc&amp;#234; usar o endere&amp;#231;o MEX para o endpoint de MEX ent&amp;#227;o ao fazer o service reference basta indicar o base address que o client se acha. Mas se voc&amp;#234; utilizar um endere&amp;#231;o diferente de MEX, ter&amp;#225; que apontar o endere&amp;#231;o completo do endpoint de MEX....&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=860</link><title>WebServices : Fazendo webServices com WCF</title><description>&lt;br&gt;At&amp;#233; o .NET 2.0 utilizavamos webServices na forma dos .ASMX criados em aplica&amp;#231;&amp;#245;es web.&lt;br&gt;&lt;br&gt;A partir do .NET 3.0 passamos a utilizar servi&amp;#231;os WCF, muito mais flexiveis que os antigos .ASMX.&lt;br&gt;&lt;br&gt;Mas e se precisarmos produzir webServices que suportem interoperabilidade com ambientes mais antigos ?&lt;br&gt;&lt;br&gt;Existem diferentes vers&amp;#245;es do protocolo SOAP e outros protocolos WS*, a quest&amp;#227;o &amp;#233; simplesmente fazer com que o WCF utilize as mesmas vers&amp;#245;es de protocolo que o antigo .ASMX.&lt;br&gt;&lt;br&gt;Para isso a solu&amp;#231;&amp;#227;o &amp;#233; muito simples : Ao inv&amp;#233;s de utilizar o wsHttpBinding, que &amp;#233; o default, devemos utilizar o basicHttpBinding, para a interoperabilidade. Isso permitir&amp;#225; que o servi&amp;#231;o WCF seja acessado como se fosse um velho .ASMX.&lt;br&gt;&lt;br&gt;Como os servi&amp;#231;os WCF podem possuir diversos endpoints, podemos criar um endpoint para compatibilidade com o ambiente legado e outro para uso dos protocolos mais atuais.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=741</link><title>WebServices : Controlando o TimeStamp com WSE</title><description>&lt;br&gt;Quando utilizamos o WSE este insere um controle de timeStamp nos pacotes SOAP. Assim sendo a hora de transmiss&amp;#227;o &amp;#233; conhecida bem como a hora de recebimento. Se houver uma diferen&amp;#231;a de tempo muito grande em rela&amp;#231;&amp;#227;o as duas o WSE recusar&amp;#225; o pacote, pois pode se tratar de algum ataque de repeti&amp;#231;&amp;#227;o de pacotes.&lt;br&gt;&lt;br&gt;Se o rel&amp;#243;gio das m&amp;#225;quinas n&amp;#227;o estiver sincronizado, este controle adicional inserido pelo WSE pode gerar problemas. Para resolver voc&amp;#234; pode corrigir uma configura&amp;#231;&amp;#227;o no web.config.&lt;br&gt;&lt;br&gt;Veja :&lt;br&gt;&lt;br&gt;&amp;lt;microsoft.web.services2&amp;gt;&lt;br&gt;&amp;lt;security&amp;gt;&lt;br&gt;    &amp;lt;timeToleranceInSeconds&amp;gt;Timeout em segundos&amp;lt;/timeToleranceInSeconds&amp;gt;&lt;br&gt;  &amp;lt;/security&amp;gt;&lt;br&gt;&amp;lt;/microsoft.web.services2&amp;gt;&lt;br&gt;&lt;br&gt;O timeout default &amp;#233; de 5 minutos. Isso pode ser aumentado, para reduzir a seguran&amp;#231;a ou reduzido, para aumentar a seguran&amp;#231;a.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=735</link><title>WebServices : Transferindo datas via WebServices</title><description>&lt;br&gt;A comunica&amp;#231;&amp;#227;o HTTP nos sugere a possibilidade de estarmos fazendo troca de dados entre aplica&amp;#231;&amp;#245;es espalhadas por diversos locais em todo o mundo.&lt;br&gt;&lt;br&gt;Por&amp;#233;m a transmiss&amp;#227;o de datas de forma t&amp;#227;o distribuida guarda algumas particularidades interessantes, que devem ser observadas.&lt;br&gt;&lt;br&gt;Imaginemos que desejamos trocar informa&amp;#231;&amp;#245;es - e um campo data entre elas - entre uma aplica&amp;#231;&amp;#227;o em Londres e uma aplica&amp;#231;&amp;#227;o em Brasilia.&lt;br&gt;&lt;br&gt;Em Londres o WebService envia uma data : 02/09/71 . Como essa data chegar&amp;#225; a Brasilia ? &lt;br&gt;&lt;br&gt;Simples : 01/09/71 21:00&lt;br&gt;&lt;br&gt;Isso por causa da diferen&amp;#231;a de fuso hor&amp;#225;rio. A data enviada pela aplica&amp;#231;&amp;#227;o em Londres &amp;#233; enviada com informa&amp;#231;&amp;#227;o data e hora e com identifica&amp;#231;&amp;#227;o de fuso hor&amp;#225;rio, o que causa essa mudan&amp;#231;a.&lt;br&gt;&lt;br&gt;Acrescente a isso as seguintes complica&amp;#231;&amp;#245;es :&lt;br&gt;&lt;br&gt;Dentro do Brasil mesmo temos v&amp;#225;rios fusos hor&amp;#225;rios, especialmente em &amp;#233;poca de hor&amp;#225;rio de ver&amp;#227;o&lt;br&gt;&lt;br&gt;As m&amp;#225;quinas podem estar com configura&amp;#231;&amp;#227;o de fuso hor&amp;#225;rio errada&lt;br&gt;&lt;br&gt;Para resolver este problema podemos lidar com a serializa&amp;#231;&amp;#227;o do webService para determinar que a informa&amp;#231;&amp;#227;o seja transmitida apenas na forma de data, sem informa&amp;#231;&amp;#227;o de hora agregada a ela. Veja como fica :&lt;br&gt;&lt;br&gt;&amp;lt;WebMethod&amp;gt; Public Sub AlteraDataNascimento ( _    codigoPessoa As Int32, _    &amp;lt;XmlElement(DataType:=&amp;quot;date&amp;quot;)&amp;gt; novaDataNascimento As DateTime)&lt;br&gt;&lt;br&gt;Simples assim, problema resolvido.&lt;br&gt;&lt;br&gt;&lt;br&gt;Esta dica foi criada por Gilberto Uchoa em seu blog que fica em http://br.thespoke.net/MyBlog/Ninguem/MyBlog.aspx&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=668</link><title>WebServices : Melhorando os recursos de cache em WebServices</title><description>&lt;br&gt;Quando utilizamos WebServices podemos configurar o cache de resposta dos webServices atrav&amp;#233;s do atributo cacheDuration. Este atributo &amp;#233; configurado em segundos, assim sendo durante este tempo o webService n&amp;#227;o ser&amp;#225; processado, seu resultado ser&amp;#225; devolvido a partir do cache.&lt;br&gt;&lt;br&gt;Por&amp;#233;m em determinados casos n&amp;#227;o desejaremos manter informa&amp;#231;&amp;#245;es em cache com base em tempo. Desejaremos manter a informa&amp;#231;&amp;#227;o em cache at&amp;#233; que os dados sofram alguma altera&amp;#231;&amp;#227;o e, quando isso acontecer, invalidar o cache imediatamente. Se utilizarmos apenas o atributo cacheDuration quando os dados forem alterados ainda assim a resposta continuar&amp;#225; sendo a do cache, at&amp;#233; que o tempo do cacheduration passe.&lt;br&gt;&lt;br&gt;O mesmo problema tamb&amp;#233;m ocorre com p&amp;#225;ginas e sugeri uma solu&amp;#231;&amp;#227;o no artigo que encontra-se em http://www.bufaloinfo.com.br/artigos/coluna11.asp , mas como resolver o problema em um WebService ?&lt;br&gt;&lt;br&gt;Atrav&amp;#233;s do objeto httpCachePolicy que pode ser acessado atrav&amp;#233;s de context.response.cache, podemos controlar os crit&amp;#233;rios para que o cache seja mantido ou n&amp;#227;o, e assim ter um maior controle sobre o processo de cache.&lt;br&gt;&lt;br&gt;    &amp;lt;WebMethod(cacheduration:=360)&amp;gt; _&lt;br&gt;    Public Function HelloWorld() As String&lt;br&gt;&lt;br&gt;        Context.Response.Cache.AddValidationCallback(AddressOf Validate, Nothing)&lt;br&gt;&lt;br&gt;        'aqui continua o processamento&lt;br&gt;&lt;br&gt;    End Function&lt;br&gt;&lt;br&gt;&lt;br&gt;    Public Sub Validate(ByVal context As HttpContext, ByVal data As Object, ByRef status As HttpValidationStatus)&lt;br&gt;&lt;br&gt;        If Not IsNothing(context.Cache(&amp;quot;dados&amp;quot;)) Then&lt;br&gt;            status = HttpValidationStatus.Valid&lt;br&gt;        Else&lt;br&gt;            'Pode-se carregar o dataset aqui&lt;br&gt;            'em seguida insere-se o dataset no cache&lt;br&gt;            context.Cache.Insert(&amp;quot;dados&amp;quot;, ds1, New Caching.CacheDependency(&amp;quot;c:\dados\arquivo.xml&amp;quot;))&lt;br&gt;        End If&lt;br&gt;    End Sub&lt;br&gt;&lt;br&gt;&lt;br&gt;Utilizamos o m&amp;#233;todo AddValidationCallBack para adicionar no httpcachepolicy uma refer&amp;#234;ncia para o m&amp;#233;todo validate. Desta forma o m&amp;#233;todo validate ser&amp;#225; chamado para verificar se o cache deve ou n&amp;#227;o ser mantido. &lt;br&gt;&lt;br&gt;Com isso ganhamos dos dois lados : mantemos os dados em cache, evitando ir ao banco e invalidamos o cache quando ocorrer mudan&amp;#231;a, ao mesmo tempo que tamb&amp;#233;m mantemos a p&amp;#225;gina em cache, evitando fazer o processamento de retorno e obtendo o m&amp;#225;ximo em performance e escalabilidade.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=645</link><title>WebServices : Utilize o atributo OneWay em WebMethods que não tenham retorno</title><description>Algumas vezes utilizamos webMethods sem retorno, como por exemplo, para inser&amp;#231;&amp;#227;o ou atualiza&amp;#231;&amp;#227;o de dados.&lt;br&gt;&lt;br&gt;Para estes casos existe um truque bem simples para otimiza&amp;#231;&amp;#227;o de performance : Podemos utilizar uma atributo junto ao WebMethod chamado OneWay. Com isso estamos informando que este m&amp;#233;todo n&amp;#227;o gera um retorno.&lt;br&gt;&lt;br&gt;Essa informa&amp;#231;&amp;#227;o faz com que o client possa disparar o m&amp;#233;todo e n&amp;#227;o ficar esperando um retorno, continuando o processamento imediatamente ap&amp;#243;s o disparo do m&amp;#233;todo. Desta forma temos uma otimiza&amp;#231;&amp;#227;o da chamada ao m&amp;#233;todo, ganhando performance.&lt;br&gt;&lt;br&gt;Na verdade OneWay &amp;#233; um par&amp;#226;metro do atributo SoapRPCMessage. Este atributo &amp;#233; usado para formatar a mensagem SOAP de acordo com o padr&amp;#227;o RPC, portanto poderia ser usado com outras finalidades, mas em nosso exemplo podemos utilizar apenas para definir que o webMethod &amp;#233; OneWay. Veja como fica :&lt;br&gt;&lt;br&gt;    &amp;lt;WebMethod(Description:=&amp;quot;Um M&amp;#233;todo Qualquer&amp;quot;), SoapRpcMethod(oneway:=True)&amp;gt; _&lt;br&gt;       Public Sub UmMetodo&lt;br&gt;&lt;br&gt;&lt;br&gt;       End Sub&lt;br&gt;&lt;br&gt;&lt;br&gt;Observe que trata-se de uma Sub. Sendo OneWay, n&amp;#227;o poderia haver retorno.&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=618</link><title>WebServices : Acessando um WebService através de um proxy com senha</title><description>&lt;br&gt;N&amp;#227;o &amp;#233; raro que precisemos criar aplica&amp;#231;&amp;#245;es em nossa empresa para acessar WebServices externos. Mas normalmente, dentro da empresa, precisamos fazer uso de servidores de proxy para acessar a web.&lt;br&gt;&lt;br&gt;Algumas vezes o servidor de proxy exige login do usu&amp;#225;rio e senha para permitir o acesso a internet. A quest&amp;#227;o &amp;#233; como transmitir isso via c&amp;#243;digo ?&lt;br&gt;&lt;br&gt;Para fazer isso devemos utilizar algumas classes adicionais do Framework. Devemos utilizar a classe NetworkCredentials para identificar a identidade do usu&amp;#225;rio e a classe WebProxy para identificar a localiza&amp;#231;&amp;#227;o do ProxyServer.&lt;br&gt;&lt;br&gt;Devemos usar a classe de acesso ao webService (gerada pelo webReference) da mesma forma como sempre fazemos, mas ligaremos o objeto webproxy na propriedade proxy antes de chamar qualquer m&amp;#233;todo.&lt;br&gt;&lt;br&gt;Veja como fica :&lt;br&gt;&lt;br&gt;        'Put user code to initialize the page here&lt;br&gt;        Dim obj As srvCadastro.devCadastro&lt;br&gt;        Dim usuario As New Net.NetworkCredential(&amp;quot;administrator&amp;quot;, &amp;quot;senha&amp;quot;)&lt;br&gt;        Dim proxy As Net.IWebProxy&lt;br&gt;&lt;br&gt;        proxy = New Net.WebProxy(&amp;quot;http://servidorproxy:80&amp;quot;)&lt;br&gt;&lt;br&gt;        proxy.Credentials = usuario&lt;br&gt;&lt;br&gt;        obj.Proxy = proxy&lt;br&gt;&lt;br&gt;Feito isso podemos utilizar os m&amp;#233;todos do WebService normalmente.&lt;br&gt;&lt;br&gt;</description></item></channel></rss>