<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>António Cruz</title><link>http://weblogs.pontonetpt.com/logus2k/</link><description>Partilha de Experiências com .NET</description><dc:language>pt-PT</dc:language><generator>RSS Generated by Dottext 0.94</generator><item><dc:creator>António José Simões da Cruz</dc:creator><title>Apresentações da Conferência Architect Insight</title><link>http://weblogs.pontonetpt.com/logus2k/posts/12841.aspx</link><pubDate>Fri, 16 Mar 2007 01:06:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/12841.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/12841.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/12841.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/12841.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=12841</trackback:ping><description>&lt;p&gt;Já estão disponíveis para download as apresentações da Conferência Architect Insight:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/uk/msdn/architecture/architectinsight/2007download.mspx"&gt;http://www.microsoft.com/uk/msdn/architecture/architectinsight/2007download.mspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;António Cruz&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Já estão disponíveis para download as apresentações da Conferência Architect Insight:</p>
<p><a href="http://www.microsoft.com/uk/msdn/architecture/architectinsight/2007download.mspx">http://www.microsoft.com/uk/msdn/architecture/architectinsight/2007download.mspx</a></p>
<p>António Cruz</p>
<p> </p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>Resumos da Conferência Microsoft Architect Insight 2007, II parte</title><link>http://weblogs.pontonetpt.com/logus2k/posts/12497.aspx</link><pubDate>Wed, 07 Mar 2007 05:58:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/12497.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/12497.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/12497.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/12497.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=12497</trackback:ping><description>&lt;p&gt;Aqui ficam os links para os resumos que compilei do segundo (e ultimo) dia da Microsoft Architect Insight 2007:&lt;/p&gt;
&lt;p&gt;- &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-active-or-passive-federation-for-the-enterprise.aspx" target="_blank"&gt;Conference Architect Insight 2007, Active or Passive Federation for the Enterprise&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-identity-scale-federation.aspx" target="_blank"&gt;Conference Architect Insight 2007, Identity Scale Federation&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-what-do-architects-do-anyway.aspx" target="_blank"&gt;Conference Architect Insight 2007, What Do Architects Do, Anyway?&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-enterprise-architect-group-final-meeting.aspx" target="_blank"&gt;Conference Architect Insight 2007, Enterprise Architect Group Final Meeting&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-solution-supply-chains.aspx" target="_blank"&gt;Conference Architect Insight 2007, Solution Supply Chains&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Antonio Cruz&lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Aqui ficam os links para os resumos que compilei do segundo (e ultimo) dia da Microsoft Architect Insight 2007:</p>
<p>- <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-active-or-passive-federation-for-the-enterprise.aspx" target="_blank">Conference Architect Insight 2007, Active or Passive Federation for the Enterprise</a><br />- <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-identity-scale-federation.aspx" target="_blank">Conference Architect Insight 2007, Identity Scale Federation</a><br />- <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-what-do-architects-do-anyway.aspx" target="_blank">Conference Architect Insight 2007, What Do Architects Do, Anyway?</a><br />- <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-enterprise-architect-group-final-meeting.aspx" target="_blank">Conference Architect Insight 2007, Enterprise Architect Group Final Meeting</a><br />- <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/06/conference-architect-insight-2007-solution-supply-chains.aspx" target="_blank">Conference Architect Insight 2007, Solution Supply Chains</a><br /><br />Antonio Cruz</p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>Resumos da Conferência Microsoft Architect Insight 2007</title><link>http://weblogs.pontonetpt.com/logus2k/posts/12474.aspx</link><pubDate>Tue, 06 Mar 2007 03:59:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/12474.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/12474.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/12474.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/12474.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=12474</trackback:ping><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Caros,&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Publiquei os meus resumos do primeiro dia da conferência em epígrafe. Peço desculpa por estar tudo em inglês mas levava muito tempo a traduzir à medida que escrevo.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl07_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-intro.aspx"&gt;&lt;font face="Verdana" size="2"&gt;Conference Architect Insight 2007, Introduction&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt; &lt;br /&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl06_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-enterprise-architect-group-first-meeting.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, Enterprise Architect Group First Meeting&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl05_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-where-to-place-your-soa-bets.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, Where to place your SOA bets?&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl04_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-clinics-the-future-of-software-industry.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, Clinics - The Future of Software Industry&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl03_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-roadmap-to-strategic-soa.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, Roadmap to Strategic SOA&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl02_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-soa-for-support-and-maintenance.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, SOA for Support and Maintenance&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl01_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-service-capsules-a-language-and-patterns-perspective-on-service-design-and-implementation.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, Service Capsules - A Language and Patterns Perspective on Service Design and Implementation&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt; &lt;br /&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl00_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-saas-as-a-disruptive-technology.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, SaaS As A Disruptive Technology&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;- &lt;/font&gt;&lt;a id="bp___v___r___postlist___EntryItems_ctl00_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-enterprise-architect-group-second-meeting.aspx"&gt;&lt;font face="Verdana"&gt;Conference Architect Insight 2007, Enterprise Architect Group Second Meeting&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;Espero que isto seja interessante para alguém. Ainda falta o segundo dia, por isso amanhã há mais...&lt;br /&gt;&lt;br /&gt;António Cruz&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p><font face="Verdana" size="2">Caros,</font></p>
<p><font face="Verdana" size="2">Publiquei os meus resumos do primeiro dia da conferência em epígrafe. Peço desculpa por estar tudo em inglês mas levava muito tempo a traduzir à medida que escrevo.</font></p>
<p><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl07_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-intro.aspx"><font face="Verdana" size="2">Conference Architect Insight 2007, Introduction</font></a><font size="2"><font face="Verdana"> <br />- </font><a id="bp___v___r___postlist___EntryItems_ctl06_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-enterprise-architect-group-first-meeting.aspx"><font face="Verdana">Conference Architect Insight 2007, Enterprise Architect Group First Meeting</font></a><br /><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl05_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-where-to-place-your-soa-bets.aspx"><font face="Verdana">Conference Architect Insight 2007, Where to place your SOA bets?</font></a><br /><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl04_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-clinics-the-future-of-software-industry.aspx"><font face="Verdana">Conference Architect Insight 2007, Clinics - The Future of Software Industry</font></a><br /><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl03_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-roadmap-to-strategic-soa.aspx"><font face="Verdana">Conference Architect Insight 2007, Roadmap to Strategic SOA</font></a><br /><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl02_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-soa-for-support-and-maintenance.aspx"><font face="Verdana">Conference Architect Insight 2007, SOA for Support and Maintenance</font></a><br /><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl01_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-service-capsules-a-language-and-patterns-perspective-on-service-design-and-implementation.aspx"><font face="Verdana">Conference Architect Insight 2007, Service Capsules - A Language and Patterns Perspective on Service Design and Implementation</font></a><font face="Verdana"> <br />- </font><a id="bp___v___r___postlist___EntryItems_ctl00_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-saas-as-a-disruptive-technology.aspx"><font face="Verdana">Conference Architect Insight 2007, SaaS As A Disruptive Technology</font></a><br /><font face="Verdana">- </font><a id="bp___v___r___postlist___EntryItems_ctl00_PostTitle" href="http://www.arquitecturadesoftware.org/blogs/antoniocruz/archive/2007/03/05/conference-architect-insight-2007-enterprise-architect-group-second-meeting.aspx"><font face="Verdana">Conference Architect Insight 2007, Enterprise Architect Group Second Meeting</font></a><br /><br /><font face="Verdana">Espero que isto seja interessante para alguém. Ainda falta o segundo dia, por isso amanhã há mais...<br /><br />António Cruz<br /></font></font><font size="2"><br /></font></p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>Como fazer serviços REST com WCF</title><link>http://weblogs.pontonetpt.com/logus2k/posts/11898.aspx</link><pubDate>Sat, 10 Feb 2007 06:44:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/11898.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/11898.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/11898.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/11898.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=11898</trackback:ping><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Muitas vezes usar SOAP não é a melhor escolha de protocolo para acesso a um serviço. Isto é tanto verdade como dizer que usar REST nem sempre faz sentido, é claro. Tal como reza a máxima: "There's no silver bullets". &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;O REST popularizou-se ligado a serviços de informação não-sensitiva (que não usem dados pessoais, pagamentos, etc.), comunitários e sem grandes preocupações de automatização do consumo e descoberta. O SOAP, por seu lado, tem ganho notoriedade por oferecer a possibilidade de ser usado no contexto de soluções empresariais que recorrem a segurança, transacções, reliable messaging, queing e federação. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Isto quer dizer que provavelmente vamos continuar a desenvolver serviços aos quais acedemos usando HTTP GET e HTTP POST ainda por muito tempo. O REST é uma manifestação do uso de HTTP GET e POST e foi associado ao AJAX e JSON mas ao contrário do que possa parecer à primeira vista, não se tratam de tecnologias antagónicas, mas sim complementares.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;As funcionalidades empresariais enunciadas acima correspondem às 4 grandes vertentes do WCF tal como ele se apresenta na actual versão 1.0. Para a versão 2.0 do WCF, está já previsto o suporte a publish-subscribing e a descoberta de serviços. Neste post, vou dar um exemplo de implementação de REST em WCF. O objectivo é duplo:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;1) Que quem se inicia no WCF não desespere por achar que é impossível ou por não conseguir fazer os serviços HTTP GET e POST que já fazia com .ASMX (ou outra tecnologia);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;2) Que possa ter a percepção do WCF como a API unificada para o desenvolvimento de serviços (tudo aquilo que se encontrava estava disperso no .ASMX, WSE, Remoting, COM/COM+ e Message Queuing).&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Segue-se um exemplo de um contrato que possibilita usar REST:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;[ServiceContract]&lt;br /&gt;public interface ICalculator&lt;br /&gt;{&lt;br /&gt;    [OperationContract(Action="*", ReplyAction="*")]&lt;br /&gt;    Message Calculate(Message message);&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Em primeiro lugar, é digno de nota é que tanto os parâmetros de input como o de output são do tipo Message. Traduzindo isto em linguagem menos "WCF-centric", temos: o método Calculate aceita qualquer tipo de input, o que faz deste parâmetro tão genérico como pode ser em WCF. O mesmo para o retorno: podemos devolver qualquer tipo de mensagem. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;A razão disto é que o WCF encapsula automaticamente todo e qualquer pedido num objecto do tipo Message, por isso se dizemos que aceitamos Message e devolvemos Message é o mesmo que dizer "aceito qualquer coisa" e "devolvo qualquer coisa".&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Em segundo lugar, note-se que tanto a propriedade Action como a ReplyAction do atributo OperationContract têm o valor "*". O WCF por default, usa SOAP. Isto quer dizer que espera receber um determinado valor num HTTP Header ou num elemento de WS-Addressing chamado "SOAPAction" e "Action", respectivamente. Se não queremos usar SOAP mas sim REST, então não queremos indicar qualquer Action/ReplyTo no momento da invocação, pelo que a equipa do WCF decidiu (e bem) que teria que haver uma forma de suportar mensagens não-SOAP. A forma que convencionaram é esta: o "*" faz com que o runtime não verifique o valor destes parâmetros e deixe a mensagem fluir para o interior da operação sem lançar a excepção: "The message with Action '' cannot be processed at the receiver".&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Segue-se um serviço de exemplo de implementação do contrato analisado:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]&lt;br /&gt;public class Calculator : ICalculator&lt;br /&gt;{&lt;br /&gt;    public Message Calculate(Message message)&lt;br /&gt;    {&lt;br /&gt;        HttpRequestMessageProperty messageProperty = &lt;br /&gt;                message.Properties["httpRequest"] as HttpRequestMessageProperty;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            if (messageProperty != null)&lt;br /&gt;            {&lt;br /&gt;                if (messageProperty.Method.Equals("GET", StringComparison.OrdinalIgnoreCase))&lt;br /&gt;                {&lt;br /&gt;                    string[] segments = OperationContext.Current.IncomingMessageHeaders.To.Segments;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                    if (segments.Length &amp;gt; 2)&lt;br /&gt;                    {&lt;br /&gt;                        string operationName = segments[2].Replace("/", string.Empty).ToLower();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;(...)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;O serviço usa um ServiceBehavior que tem na propriedade AddressFilterMode o valor AddressFilterMode.Any. Isto quer dizer que não será analisado/validado o url usado para aceder ao endpoint do serviço. Por outras palavras, se podemos enviar qualquer payload *e* podemos usar qualquer tipo de sintaxe no url do serviço, temos o caminho aberto para usar REST com WCF. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Já no interior da operação, uso um HttpRequestMessageProperty para aceder ao pedido HTTP raw por via da propriedade httpRequest deste objecto. Assim, é fácil determinar qual o verbo HTTP que foi usado e agir em conformidade. Posso por exemplo processar os GET (select) de uma maneira e os POST (update) de outra, tal como convencionado em REST. E, é claro, processar qualquer outro verbo aceite pelo servidor da mesma forma (INSERT, APPEND, DEBUG, DELETE, etc.). &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Finalmente, acedo a IncomingMessageHeaders para determinar o nome da operação. É interessante analisar os valores tanto de HttpRequestMessageProperty como de IncomingMessageHeaders, por isso sugiro que façam debug a esses objectos e naveguem pela informação que disponibilizam.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Este exemplo deixa claro como é fácil suportar REST em WCF. Considero boa prática suportar diversos protocolos de acesso à mesma funcionalidade, sempre que possível: por exemplo, suportar REST, JSON e SOAP, nesta altura, dá boas garantias de interoperabilidade com mashups de AJAX e deixa a porta aberta para o acesso via proxies de SOAP em C#, Java, PHP, Perl, etc.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;António Cruz&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;[Cross-Posted de &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"&gt;&lt;font face="Verdana" size="2"&gt;http://www.arquitecturadesoftware.org/blogs/antoniocruz&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;]&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;&lt;/font&gt; &lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p><font face="Verdana" size="2">Muitas vezes usar SOAP não é a melhor escolha de protocolo para acesso a um serviço. Isto é tanto verdade como dizer que usar REST nem sempre faz sentido, é claro. Tal como reza a máxima: "There's no silver bullets". </font></p>
<p><font face="Verdana" size="2">O REST popularizou-se ligado a serviços de informação não-sensitiva (que não usem dados pessoais, pagamentos, etc.), comunitários e sem grandes preocupações de automatização do consumo e descoberta. O SOAP, por seu lado, tem ganho notoriedade por oferecer a possibilidade de ser usado no contexto de soluções empresariais que recorrem a segurança, transacções, reliable messaging, queing e federação. </font></p>
<p><font face="Verdana" size="2">Isto quer dizer que provavelmente vamos continuar a desenvolver serviços aos quais acedemos usando HTTP GET e HTTP POST ainda por muito tempo. O REST é uma manifestação do uso de HTTP GET e POST e foi associado ao AJAX e JSON mas ao contrário do que possa parecer à primeira vista, não se tratam de tecnologias antagónicas, mas sim complementares.</font></p>
<p><font face="Verdana" size="2">As funcionalidades empresariais enunciadas acima correspondem às 4 grandes vertentes do WCF tal como ele se apresenta na actual versão 1.0. Para a versão 2.0 do WCF, está já previsto o suporte a publish-subscribing e a descoberta de serviços. Neste post, vou dar um exemplo de implementação de REST em WCF. O objectivo é duplo:</font></p>
<p><font face="Verdana" size="2">1) Que quem se inicia no WCF não desespere por achar que é impossível ou por não conseguir fazer os serviços HTTP GET e POST que já fazia com .ASMX (ou outra tecnologia);</font></p>
<p><font face="Verdana" size="2">2) Que possa ter a percepção do WCF como a API unificada para o desenvolvimento de serviços (tudo aquilo que se encontrava estava disperso no .ASMX, WSE, Remoting, COM/COM+ e Message Queuing).</font></p>
<p><font face="Verdana" size="2">Segue-se um exemplo de um contrato que possibilita usar REST:</font></p>
<p><font face="Verdana" size="2">[ServiceContract]<br />public interface ICalculator<br />{<br />    [OperationContract(Action="*", ReplyAction="*")]<br />    Message Calculate(Message message);<br />}</font></p>
<p><font face="Verdana" size="2">Em primeiro lugar, é digno de nota é que tanto os parâmetros de input como o de output são do tipo Message. Traduzindo isto em linguagem menos "WCF-centric", temos: o método Calculate aceita qualquer tipo de input, o que faz deste parâmetro tão genérico como pode ser em WCF. O mesmo para o retorno: podemos devolver qualquer tipo de mensagem. </font></p>
<p><font face="Verdana" size="2">A razão disto é que o WCF encapsula automaticamente todo e qualquer pedido num objecto do tipo Message, por isso se dizemos que aceitamos Message e devolvemos Message é o mesmo que dizer "aceito qualquer coisa" e "devolvo qualquer coisa".</font></p>
<p><font face="Verdana" size="2">Em segundo lugar, note-se que tanto a propriedade Action como a ReplyAction do atributo OperationContract têm o valor "*". O WCF por default, usa SOAP. Isto quer dizer que espera receber um determinado valor num HTTP Header ou num elemento de WS-Addressing chamado "SOAPAction" e "Action", respectivamente. Se não queremos usar SOAP mas sim REST, então não queremos indicar qualquer Action/ReplyTo no momento da invocação, pelo que a equipa do WCF decidiu (e bem) que teria que haver uma forma de suportar mensagens não-SOAP. A forma que convencionaram é esta: o "*" faz com que o runtime não verifique o valor destes parâmetros e deixe a mensagem fluir para o interior da operação sem lançar a excepção: "The message with Action '' cannot be processed at the receiver".</font></p>
<p><font face="Verdana" size="2">Segue-se um serviço de exemplo de implementação do contrato analisado:</font></p>
<p><font face="Verdana" size="2">[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]<br />public class Calculator : ICalculator<br />{<br />    public Message Calculate(Message message)<br />    {<br />        HttpRequestMessageProperty messageProperty = <br />                message.Properties["httpRequest"] as HttpRequestMessageProperty;</font></p>
<p><font face="Verdana" size="2">            if (messageProperty != null)<br />            {<br />                if (messageProperty.Method.Equals("GET", StringComparison.OrdinalIgnoreCase))<br />                {<br />                    string[] segments = OperationContext.Current.IncomingMessageHeaders.To.Segments;</font></p>
<p><font face="Verdana" size="2">                    if (segments.Length &gt; 2)<br />                    {<br />                        string operationName = segments[2].Replace("/", string.Empty).ToLower();</font></p>
<p><font face="Verdana" size="2">(...)</font></p>
<p><font face="Verdana" size="2">O serviço usa um ServiceBehavior que tem na propriedade AddressFilterMode o valor AddressFilterMode.Any. Isto quer dizer que não será analisado/validado o url usado para aceder ao endpoint do serviço. Por outras palavras, se podemos enviar qualquer payload *e* podemos usar qualquer tipo de sintaxe no url do serviço, temos o caminho aberto para usar REST com WCF. </font></p>
<p><font face="Verdana" size="2">Já no interior da operação, uso um HttpRequestMessageProperty para aceder ao pedido HTTP raw por via da propriedade httpRequest deste objecto. Assim, é fácil determinar qual o verbo HTTP que foi usado e agir em conformidade. Posso por exemplo processar os GET (select) de uma maneira e os POST (update) de outra, tal como convencionado em REST. E, é claro, processar qualquer outro verbo aceite pelo servidor da mesma forma (INSERT, APPEND, DEBUG, DELETE, etc.). </font></p>
<p><font face="Verdana" size="2">Finalmente, acedo a IncomingMessageHeaders para determinar o nome da operação. É interessante analisar os valores tanto de HttpRequestMessageProperty como de IncomingMessageHeaders, por isso sugiro que façam debug a esses objectos e naveguem pela informação que disponibilizam.</font></p>
<p><font face="Verdana" size="2">Este exemplo deixa claro como é fácil suportar REST em WCF. Considero boa prática suportar diversos protocolos de acesso à mesma funcionalidade, sempre que possível: por exemplo, suportar REST, JSON e SOAP, nesta altura, dá boas garantias de interoperabilidade com mashups de AJAX e deixa a porta aberta para o acesso via proxies de SOAP em C#, Java, PHP, Perl, etc.</font></p>
<p><font face="Verdana" size="2">António Cruz</font></p>
<p><font face="Verdana" size="2">[Cross-Posted de <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"><font face="Verdana" size="2">http://www.arquitecturadesoftware.org/blogs/antoniocruz</font></a><font face="Verdana" size="2">]</font></font></p>
<p><font face="Verdana" size="2"></font> </p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>WSDL Merger</title><link>http://weblogs.pontonetpt.com/logus2k/posts/11828.aspx</link><pubDate>Wed, 07 Feb 2007 02:27:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/11828.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/11828.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/11828.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/11828.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=11828</trackback:ping><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;O contrato WSDL gerado automaticamente pelos serviços desenvolvidos com WCF é regra geral, composto por 4 ficheiros: 2 .wsdl e dois .xsd, cada um deles disponível num url diferente. Uma necessidade que tenho sentido é a de disponibilizar o contrato do serviço em apenas um ficheiro, de modo a ser mais fácil distribuir e arquivar. &lt;br /&gt;&lt;br /&gt;Depois de fazer o merge manual destes ficheiros algumas vezes, cheguei à conclusão que faz sentido usar um utilitário que faça a mesma tarefa por mim. O código que se segue não será provavelmente bullet-proof para todo e qualquer .wsdl que contenha referências, mas para os serviços que desenvolvi, funciona lindamente:&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Xml;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;namespace MyCompany.ApplicationBlocks.Metadata&lt;br /&gt;{&lt;br /&gt;    public class WsdlMerger&lt;br /&gt;    {&lt;br /&gt;        private static XmlNamespaceManager _namespaceManager = null;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;        public static string Merge(string mainWsdlUrlAddress)&lt;br /&gt;        {&lt;br /&gt;            _namespaceManager = new XmlNamespaceManager(new NameTable());&lt;br /&gt;            _namespaceManager.AddNamespace("wsdl", "&lt;/font&gt;&lt;a href="http://schemas.xmlsoap.org/wsdl/" mce_href="http://schemas.xmlsoap.org/wsdl/"&gt;&lt;font face="Verdana" size="2"&gt;http://schemas.xmlsoap.org/wsdl/&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;");&lt;br /&gt;            _namespaceManager.AddNamespace("xsd", "&lt;/font&gt;&lt;a href="http://www.w3.org/2001/XMLSchema" mce_href="http://www.w3.org/2001/XMLSchema"&gt;&lt;font face="Verdana" size="2"&gt;http://www.w3.org/2001/XMLSchema&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;");&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            XmlDocument wsdl = Load(mainWsdlUrlAddress);&lt;br /&gt;            ResolveReferences(wsdl, wsdl);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            Clean(wsdl);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            return wsdl.OuterXml;&lt;br /&gt;        }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;        private static XmlDocument Load(string urlAddress)&lt;br /&gt;        {&lt;br /&gt;            XmlDocument xmlDocument = new XmlDocument();&lt;br /&gt;            xmlDocument.Load(urlAddress);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            return xmlDocument;&lt;br /&gt;        }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;        private static void ResolveReferences(XmlDocument mainDocument, XmlDocument currentDocument)&lt;br /&gt;        {&lt;br /&gt;            XmlNodeList wsdlImports = currentDocument.SelectNodes("/wsdl:definitions/wsdl:import", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            foreach (XmlNode wsdlImport in wsdlImports)&lt;br /&gt;            {&lt;br /&gt;                string wsdlAddress = wsdlImport.SelectSingleNode("@location").InnerText;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                XmlDocument wsdl = Load(wsdlAddress);&lt;br /&gt;                ImportWsdlNode(mainDocument, wsdl, wsdlImport);&lt;br /&gt;                ResolveReferences(mainDocument, wsdl);&lt;br /&gt;            }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            XmlNodeList xsdImports = currentDocument.SelectNodes("/wsdl:definitions/wsdl:types/xsd:schema/xsd:import", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            foreach (XmlNode xsdImport in xsdImports)&lt;br /&gt;            {&lt;br /&gt;                string xsdAddress = xsdImport.SelectSingleNode("@schemaLocation").InnerText;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                XmlDocument xsd = Load(xsdAddress);&lt;br /&gt;                ImportXsdNode(mainDocument, xsd, xsdImport);&lt;br /&gt;                ResolveReferences(mainDocument, xsd);&lt;br /&gt;            }&lt;br /&gt;        }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;        private static void ImportWsdlNode(XmlDocument mainDocument, XmlDocument currentWsdlDocument, XmlNode wsdlImport)&lt;br /&gt;        {&lt;br /&gt;            XmlNodeList nodesToImport = currentWsdlDocument.SelectNodes("/wsdl:definitions/*[not(self::wsdl:types) and not(self::wsdl:import)]", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            foreach (XmlNode nodeToImport in nodesToImport)&lt;br /&gt;            {&lt;br /&gt;                XmlNode referenceNode = mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:types", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                if (referenceNode == null)&lt;br /&gt;                {&lt;br /&gt;                    referenceNode = mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:import", _namespaceManager);&lt;br /&gt;                }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                string wsdlTargetNamespace = mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:import/@namespace", _namespaceManager).Value;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                if (wsdlTargetNamespace != null)&lt;br /&gt;                {&lt;br /&gt;                    XmlNode targetNamespaceAttribute = mainDocument.SelectSingleNode("wsdl:definitions/@targetNamespace", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                    if (targetNamespaceAttribute != null)&lt;br /&gt;                    {&lt;br /&gt;                        targetNamespaceAttribute.Value = wsdlTargetNamespace;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                XmlNode tnsPrefixNamespace = mainDocument.SelectSingleNode("/wsdl:definitions/namespace::tns", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                if (tnsPrefixNamespace != null)&lt;br /&gt;                {&lt;br /&gt;                    tnsPrefixNamespace.Value = wsdlTargetNamespace;&lt;br /&gt;                }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                XmlNode importedNode = mainDocument.ImportNode(nodeToImport, true);&lt;br /&gt;                mainDocument.SelectSingleNode("/wsdl:definitions", _namespaceManager).InsertAfter(importedNode, referenceNode);&lt;br /&gt;            }&lt;br /&gt;        }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;        private static void ImportXsdNode(XmlDocument mainDocument, XmlDocument currentXsdDocument, XmlNode xsdImport)&lt;br /&gt;        {&lt;br /&gt;            List&amp;lt;string&amp;gt; namespacesToExclude = new List&amp;lt;string&amp;gt;();&lt;br /&gt;            namespacesToExclude.Add("&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/2003/10/Serialization/" mce_href="http://schemas.microsoft.com/2003/10/Serialization/"&gt;&lt;font face="Verdana" size="2"&gt;http://schemas.microsoft.com/2003/10/Serialization/&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;");&lt;br /&gt;            &lt;br /&gt;            XmlNode targetNamespace = currentXsdDocument.SelectSingleNode("/xsd:schema/@targetNamespace", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            if (targetNamespace != null &amp;amp;&amp;amp; !namespacesToExclude.Contains(targetNamespace.Value))&lt;br /&gt;            {&lt;br /&gt;                XmlNodeList nodesToImport = currentXsdDocument.SelectNodes("/xsd:schema", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;                foreach (XmlNode nodeToImport in nodesToImport)&lt;br /&gt;                {&lt;br /&gt;                    XmlNode importedNode = mainDocument.ImportNode(nodeToImport, true);&lt;br /&gt;                    mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:types", _namespaceManager).PrependChild(importedNode);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;        private static void Clean(XmlDocument wsdl)&lt;br /&gt;        {&lt;br /&gt;            XmlNode wsdlImportNode = wsdl.SelectSingleNode("/wsdl:definitions/wsdl:import", _namespaceManager);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;            if (wsdlImportNode != null)&lt;br /&gt;            {&lt;br /&gt;                wsdl.SelectSingleNode("/wsdl:definitions", _namespaceManager).RemoveChild(wsdlImportNode);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Aqui está um exemplo de consumo:&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.IO;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;using MyCompany.ApplicationBlocks.Metadata;&lt;br /&gt;&lt;br /&gt;namespace WSDLMerger&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main()&lt;br /&gt;        {&lt;br /&gt;            string fullWsdl = WsdlMerger.Merge("&lt;/font&gt;&lt;a href="http://mycompany/myservice.svc?wsdl" mce_href="http://mycompany/myservice.svc?wsdl"&gt;&lt;font face="Verdana" size="2"&gt;http://mycompany/myservice.svc?wsdl&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;");&lt;br /&gt;            File.WriteAllText(@"C:\FullWSDL.wsdl", fullWsdl);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Podem facilmente ver que o código é susceptível de várias melhorias. A ideia foi disponibilizá-lo a quem possa ser útil desde já.&lt;br /&gt;&lt;br /&gt;António Cruz&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;font face="Verdana" size="2"&gt;[Cross-Posted de &lt;/font&gt;&lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"&gt;&lt;font face="Verdana" size="2"&gt;http://www.arquitecturadesoftware.org/blogs/antoniocruz&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;]&lt;/font&gt;&lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p><font face="Verdana" size="2">O contrato WSDL gerado automaticamente pelos serviços desenvolvidos com WCF é regra geral, composto por 4 ficheiros: 2 .wsdl e dois .xsd, cada um deles disponível num url diferente. Uma necessidade que tenho sentido é a de disponibilizar o contrato do serviço em apenas um ficheiro, de modo a ser mais fácil distribuir e arquivar. <br /><br />Depois de fazer o merge manual destes ficheiros algumas vezes, cheguei à conclusão que faz sentido usar um utilitário que faça a mesma tarefa por mim. O código que se segue não será provavelmente bullet-proof para todo e qualquer .wsdl que contenha referências, mas para os serviços que desenvolvi, funciona lindamente:<br /><br />using System;<br />using System.Collections.Generic;<br />using System.Xml;</font></p>
<p><font face="Verdana" size="2">namespace MyCompany.ApplicationBlocks.Metadata<br />{<br />    public class WsdlMerger<br />    {<br />        private static XmlNamespaceManager _namespaceManager = null;</font></p>
<p><font face="Verdana" size="2">        public static string Merge(string mainWsdlUrlAddress)<br />        {<br />            _namespaceManager = new XmlNamespaceManager(new NameTable());<br />            _namespaceManager.AddNamespace("wsdl", "</font><a href="http://schemas.xmlsoap.org/wsdl/" mce_href="http://schemas.xmlsoap.org/wsdl/"><font face="Verdana" size="2">http://schemas.xmlsoap.org/wsdl/</font></a><font face="Verdana" size="2">");<br />            _namespaceManager.AddNamespace("xsd", "</font><a href="http://www.w3.org/2001/XMLSchema" mce_href="http://www.w3.org/2001/XMLSchema"><font face="Verdana" size="2">http://www.w3.org/2001/XMLSchema</font></a><font face="Verdana" size="2">");</font></p>
<p><font face="Verdana" size="2">            XmlDocument wsdl = Load(mainWsdlUrlAddress);<br />            ResolveReferences(wsdl, wsdl);</font></p>
<p><font face="Verdana" size="2">            Clean(wsdl);</font></p>
<p><font face="Verdana" size="2">            return wsdl.OuterXml;<br />        }</font></p>
<p><font face="Verdana" size="2">        private static XmlDocument Load(string urlAddress)<br />        {<br />            XmlDocument xmlDocument = new XmlDocument();<br />            xmlDocument.Load(urlAddress);</font></p>
<p><font face="Verdana" size="2">            return xmlDocument;<br />        }</font></p>
<p><font face="Verdana" size="2">        private static void ResolveReferences(XmlDocument mainDocument, XmlDocument currentDocument)<br />        {<br />            XmlNodeList wsdlImports = currentDocument.SelectNodes("/wsdl:definitions/wsdl:import", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">            foreach (XmlNode wsdlImport in wsdlImports)<br />            {<br />                string wsdlAddress = wsdlImport.SelectSingleNode("@location").InnerText;</font></p>
<p><font face="Verdana" size="2">                XmlDocument wsdl = Load(wsdlAddress);<br />                ImportWsdlNode(mainDocument, wsdl, wsdlImport);<br />                ResolveReferences(mainDocument, wsdl);<br />            }</font></p>
<p><font face="Verdana" size="2">            XmlNodeList xsdImports = currentDocument.SelectNodes("/wsdl:definitions/wsdl:types/xsd:schema/xsd:import", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">            foreach (XmlNode xsdImport in xsdImports)<br />            {<br />                string xsdAddress = xsdImport.SelectSingleNode("@schemaLocation").InnerText;</font></p>
<p><font face="Verdana" size="2">                XmlDocument xsd = Load(xsdAddress);<br />                ImportXsdNode(mainDocument, xsd, xsdImport);<br />                ResolveReferences(mainDocument, xsd);<br />            }<br />        }</font></p>
<p><font face="Verdana" size="2">        private static void ImportWsdlNode(XmlDocument mainDocument, XmlDocument currentWsdlDocument, XmlNode wsdlImport)<br />        {<br />            XmlNodeList nodesToImport = currentWsdlDocument.SelectNodes("/wsdl:definitions/*[not(self::wsdl:types) and not(self::wsdl:import)]", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">            foreach (XmlNode nodeToImport in nodesToImport)<br />            {<br />                XmlNode referenceNode = mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:types", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">                if (referenceNode == null)<br />                {<br />                    referenceNode = mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:import", _namespaceManager);<br />                }</font></p>
<p><font face="Verdana" size="2">                string wsdlTargetNamespace = mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:import/@namespace", _namespaceManager).Value;</font></p>
<p><font face="Verdana" size="2">                if (wsdlTargetNamespace != null)<br />                {<br />                    XmlNode targetNamespaceAttribute = mainDocument.SelectSingleNode("wsdl:definitions/@targetNamespace", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">                    if (targetNamespaceAttribute != null)<br />                    {<br />                        targetNamespaceAttribute.Value = wsdlTargetNamespace;<br />                    }<br />                }</font></p>
<p><font face="Verdana" size="2">                XmlNode tnsPrefixNamespace = mainDocument.SelectSingleNode("/wsdl:definitions/namespace::tns", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">                if (tnsPrefixNamespace != null)<br />                {<br />                    tnsPrefixNamespace.Value = wsdlTargetNamespace;<br />                }</font></p>
<p><font face="Verdana" size="2">                XmlNode importedNode = mainDocument.ImportNode(nodeToImport, true);<br />                mainDocument.SelectSingleNode("/wsdl:definitions", _namespaceManager).InsertAfter(importedNode, referenceNode);<br />            }<br />        }</font></p>
<p><font face="Verdana" size="2">        private static void ImportXsdNode(XmlDocument mainDocument, XmlDocument currentXsdDocument, XmlNode xsdImport)<br />        {<br />            List&lt;string&gt; namespacesToExclude = new List&lt;string&gt;();<br />            namespacesToExclude.Add("</font><a href="http://schemas.microsoft.com/2003/10/Serialization/" mce_href="http://schemas.microsoft.com/2003/10/Serialization/"><font face="Verdana" size="2">http://schemas.microsoft.com/2003/10/Serialization/</font></a><font face="Verdana" size="2">");<br />            <br />            XmlNode targetNamespace = currentXsdDocument.SelectSingleNode("/xsd:schema/@targetNamespace", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">            if (targetNamespace != null &amp;&amp; !namespacesToExclude.Contains(targetNamespace.Value))<br />            {<br />                XmlNodeList nodesToImport = currentXsdDocument.SelectNodes("/xsd:schema", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">                foreach (XmlNode nodeToImport in nodesToImport)<br />                {<br />                    XmlNode importedNode = mainDocument.ImportNode(nodeToImport, true);<br />                    mainDocument.SelectSingleNode("/wsdl:definitions/wsdl:types", _namespaceManager).PrependChild(importedNode);<br />                }<br />            }<br />        }</font></p>
<p><font face="Verdana" size="2">        private static void Clean(XmlDocument wsdl)<br />        {<br />            XmlNode wsdlImportNode = wsdl.SelectSingleNode("/wsdl:definitions/wsdl:import", _namespaceManager);</font></p>
<p><font face="Verdana" size="2">            if (wsdlImportNode != null)<br />            {<br />                wsdl.SelectSingleNode("/wsdl:definitions", _namespaceManager).RemoveChild(wsdlImportNode);<br />            }<br />        }<br />    }<br />}<br /><br />Aqui está um exemplo de consumo:<br /><br />using System;<br />using System.IO;</font></p>
<p><font face="Verdana" size="2">using MyCompany.ApplicationBlocks.Metadata;<br /><br />namespace WSDLMerger<br />{<br />    class Program<br />    {<br />        static void Main()<br />        {<br />            string fullWsdl = WsdlMerger.Merge("</font><a href="http://mycompany/myservice.svc?wsdl" mce_href="http://mycompany/myservice.svc?wsdl"><font face="Verdana" size="2">http://mycompany/myservice.svc?wsdl</font></a><font size="2"><font face="Verdana">");<br />            File.WriteAllText(@"C:\FullWSDL.wsdl", fullWsdl);<br />        }<br />    }<br />}<br /><br />Podem facilmente ver que o código é susceptível de várias melhorias. A ideia foi disponibilizá-lo a quem possa ser útil desde já.<br /><br />António Cruz<br /><br /></font></font></p>
<p mce_keep="true"><font face="Verdana" size="2">[Cross-Posted de </font><a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"><font face="Verdana" size="2">http://www.arquitecturadesoftware.org/blogs/antoniocruz</font></a><font face="Verdana" size="2">]</font></p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>WCF Programmer's Toolbox</title><link>http://weblogs.pontonetpt.com/logus2k/posts/11721.aspx</link><pubDate>Fri, 02 Feb 2007 05:27:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/11721.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/11721.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/11721.aspx#feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/11721.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=11721</trackback:ping><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Enquanto programador, acabei por reunir um conjunto de utilitários e práticas que me permitem maior eficácia no desempenho das minhas tarefas de desenvolvimento, debugging e monitorização de serviços. Neste post vou identificar o conjunto de programas que tenho usado, bem como descrever aquela que penso ser a sua utilidade, de acordo com os objectivos que referi.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;1) Svcutil.exe - não uso o Add Service Reference. Se apenas quero gerar um proxy para o serviço, dispenso a verborreia que obtenho quando uso o output.config gerado e dispenso a criação da pasta respectiva na solução. Na maioria dos casos, na configuração só preciso dos elementos ABC (address, binding e contract) e um ou outro parâmetro de tuning, como por exemplo o "maxReceivedMessageSize". Na verdade, considero uma boa prática *não* usar o Add Service Reference. Dito isto, às vezes dá jeito usar a feature como "truque" para obter automaticamente a lista de todos os parâmetros e respectivos valores por default, que por sua vez nem sempre são fáceis de identificar na documentação.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;2) &lt;/font&gt;&lt;a class="" title="Fiddler" href="http://www.fiddlertool.com/fiddler/" target="_blank" mce_href="http://www.fiddlertool.com/fiddler/"&gt;&lt;font face="Verdana" size="2"&gt;Microsoft Fiddler&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; - Para simular clientes POX/REST usando o basicHttpBinding, esta ferramenta serve lindamente. É fácil manipular os headers e o body da mensagem enviada, descompacta a stream da resposta quando esta vem gzipped e mostra a comunicação em raw, isto é, sem formatação, o que às vezes também dá jeito, principalmente para detectar problemas no encoding da stream da resposta. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt; 3) &lt;/font&gt;&lt;a class="" title="tcpTrace" href="http://www.pocketsoap.com/tcptrace/" target="_blank" mce_href="http://www.pocketsoap.com/tcptrace/"&gt;&lt;font face="Verdana" size="2"&gt;tcpTrace&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; - Há muitos sniffers de rede (por exemplo, o Ethereal é muito bom), mas esta aplicação serve bem quando só quero mesmo fazer um pedido com alteração mínima da configuração (só mudo o endpoint para ser aquele em que escuta o tcpTrace). Podia usar o SvcConfigEditor.exe e alterar o .config para obter a mesma informação em ficheiros, mas geralmente sou mais rápido a i) alterar o endpoint, ii) lançar o tcpTrace e iii) monitorizar *live* a comunicação.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt; 4) &lt;/font&gt;&lt;a class="" title="SoapUI" href="http://www.soapui.org/" target="_blank" mce_href="http://www.soapui.org/"&gt;&lt;font face="Verdana" size="2"&gt;SoapUI&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; - Entre outras, esta aplicação tem uma funcionalidade que aprecio bastante: dou-lhe um endpoint ou um ficheiro que contenha um WSDL e obtenho a listagem de operações e o respectivo conjunto de sample SOAP requests que posso imediatamente usar para provocar um pedido ao serviço fazendo "Play".&lt;/font&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;font face="Verdana" size="2"&gt;[Cross-Posted de &lt;/font&gt;&lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"&gt;&lt;font face="Verdana" size="2"&gt;http://www.arquitecturadesoftware.org/blogs/antoniocruz&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;]&lt;/font&gt;&lt;/p&gt;
&lt;p mce_keep="true"&gt;&lt;font face="Verdana" size="2"&gt;&lt;/font&gt; &lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p><font face="Verdana" size="2">Enquanto programador, acabei por reunir um conjunto de utilitários e práticas que me permitem maior eficácia no desempenho das minhas tarefas de desenvolvimento, debugging e monitorização de serviços. Neste post vou identificar o conjunto de programas que tenho usado, bem como descrever aquela que penso ser a sua utilidade, de acordo com os objectivos que referi.</font></p>
<p><font face="Verdana" size="2">1) Svcutil.exe - não uso o Add Service Reference. Se apenas quero gerar um proxy para o serviço, dispenso a verborreia que obtenho quando uso o output.config gerado e dispenso a criação da pasta respectiva na solução. Na maioria dos casos, na configuração só preciso dos elementos ABC (address, binding e contract) e um ou outro parâmetro de tuning, como por exemplo o "maxReceivedMessageSize". Na verdade, considero uma boa prática *não* usar o Add Service Reference. Dito isto, às vezes dá jeito usar a feature como "truque" para obter automaticamente a lista de todos os parâmetros e respectivos valores por default, que por sua vez nem sempre são fáceis de identificar na documentação.</font></p>
<p><font face="Verdana" size="2">2) </font><a class="" title="Fiddler" href="http://www.fiddlertool.com/fiddler/" target="_blank" mce_href="http://www.fiddlertool.com/fiddler/"><font face="Verdana" size="2">Microsoft Fiddler</font></a><font face="Verdana" size="2"> - Para simular clientes POX/REST usando o basicHttpBinding, esta ferramenta serve lindamente. É fácil manipular os headers e o body da mensagem enviada, descompacta a stream da resposta quando esta vem gzipped e mostra a comunicação em raw, isto é, sem formatação, o que às vezes também dá jeito, principalmente para detectar problemas no encoding da stream da resposta. </font></p>
<p><font face="Verdana" size="2"> 3) </font><a class="" title="tcpTrace" href="http://www.pocketsoap.com/tcptrace/" target="_blank" mce_href="http://www.pocketsoap.com/tcptrace/"><font face="Verdana" size="2">tcpTrace</font></a><font face="Verdana" size="2"> - Há muitos sniffers de rede (por exemplo, o Ethereal é muito bom), mas esta aplicação serve bem quando só quero mesmo fazer um pedido com alteração mínima da configuração (só mudo o endpoint para ser aquele em que escuta o tcpTrace). Podia usar o SvcConfigEditor.exe e alterar o .config para obter a mesma informação em ficheiros, mas geralmente sou mais rápido a i) alterar o endpoint, ii) lançar o tcpTrace e iii) monitorizar *live* a comunicação.</font></p>
<p><font face="Verdana" size="2"> 4) </font><a class="" title="SoapUI" href="http://www.soapui.org/" target="_blank" mce_href="http://www.soapui.org/"><font face="Verdana" size="2">SoapUI</font></a><font face="Verdana" size="2"> - Entre outras, esta aplicação tem uma funcionalidade que aprecio bastante: dou-lhe um endpoint ou um ficheiro que contenha um WSDL e obtenho a listagem de operações e o respectivo conjunto de sample SOAP requests que posso imediatamente usar para provocar um pedido ao serviço fazendo "Play".</font></p>
<p mce_keep="true"><font face="Verdana" size="2">[Cross-Posted de </font><a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"><font face="Verdana" size="2">http://www.arquitecturadesoftware.org/blogs/antoniocruz</font></a><font face="Verdana" size="2">]</font></p>
<p mce_keep="true"><font face="Verdana" size="2"></font> </p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>WCF Starter's Roadmap</title><link>http://weblogs.pontonetpt.com/logus2k/posts/11699.aspx</link><pubDate>Thu, 01 Feb 2007 06:46:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/11699.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/11699.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/11699.aspx#feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/11699.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=11699</trackback:ping><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Por eventualmente ser de interesse para quem pretende iniciar o estudo do WCF, resolvi fazer este post. A ideia é identificar quais são os requisitos desejáveis para serem WCF starters e, de seguida, apresentar alguns recursos que considero de qualidade para quem deseja aprofundar conhecimentos na matéria:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;font face="Verdana" size="2"&gt;Requisitos: &lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;- Programação em .NET, especialmente componentes, usando interfaces, atributos, genéricos, threading, herança e transacções. &lt;br /&gt;- Bons conhecimentos de arquitecturas distribuídas, em especial usando web services e/ou remoting e queuing, WSE e/ou .ASMX, COM e/ou DCOM.&lt;br /&gt;- Conhecimentos dos core standards usados em web services: REST, JSON, XML, XML Namespaces, XML Schemas, WSDL, WS-Addressing.&lt;br /&gt;- Conhecimentos funcionais de standards WS-*, particularmente WS-Security, WS-Reliable Messaging, WS-Transactions e WS-Trust.&lt;br /&gt;- Compreensão de conceitos ligados a SOA: Orientação a Serviços, Messaging, Concorrência, Transacções Distribuídas, P2P, Federação, Single Sign-On.&lt;br /&gt;- Familiaridade com design patterns como proxy, broker, publish-subscriber, data transfer object, adapter, façade e singleton.&lt;br /&gt;- Muita vontade de aprender a usar a software factory template para desenvolvimento de serviços mais avançada que existe.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana"&gt;&lt;font size="2"&gt;&lt;strong&gt;Recursos&lt;/strong&gt;:&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;- Windows Communication Foundation Hands-On, Craig McMurtry, SAMS, 0672328771. Este livro é bastante acessível para quem começar a ler os primeiros textos sobre WCF. Não sendo exaustivo em nenhum tópico, apresenta o mérito de incluir um pouco de informação sobre cada tema relacionado com esta tecnologia, diversidade esta que nem sempre encontrei em outras fontes: P2P, CardSpace, Federação, REST, Custom Behaviors, Custom Transports, etc.&lt;br /&gt;- Programming WCF Services, Juval Löwy, O'Reilly Media, 0596526997. Ainda só disponível em "Rough Cuts" na O'Reilly, este é provavelmente o melhor livro disponível até à data. Bastante orientado a aspectos práticos e com muitos exemplos de código reutilizável em projecto. A não perder: todos os exemplos de código disponível no site IDesign.net. Não comecem a desenvolver/testar uma nova funcionalidade a partir do zero, i. é, sem procurar se existe já um exemplo feito. Usando um exemplo como template temos acesso a um excelente ramp-up.&lt;br /&gt;- Windows SDK. Disponibilidade obrigatória como Programmer's Reference no dia-a-dia.&lt;br /&gt;- &lt;/font&gt;&lt;a class="" title="wcf.netfx3.com" href="http://wcf.netfx3.com/" target="_blank" mce_href="http://wcf.netfx3.com/"&gt;&lt;font face="Verdana" size="2"&gt;http://wcf.netfx3.com/&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;. Site da comunidade de WCF. Aqui temos acesso a apresentações, artigos, vídeos, webcasts, podcasts, exemplos de código e até acesso a fazer um Hands-On Labs on-line. Aqui, sugiro começarem por ler os whitepapers referidos e depois ver alguns videos, por exemplo.&lt;br /&gt;- &lt;/font&gt;&lt;a class="" title="WCF Forum" href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=118&amp;amp;SiteID=1" target="_blank" mce_href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=118&amp;amp;SiteID=1"&gt;&lt;font face="Verdana" size="2"&gt;WCF Forum&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;. Este é o forum a ter em conta sobre WCF. Seguido atentamente por elementos da equipa de desenvolvimento, é fácil colocar uma dúvida que seja respondida rapidamente.&lt;br /&gt;- Finalmente, o recurso mais importante: nós próprios! Não há *nada* que substitua a experimentação sucessiva e metódica das features e o passar por problemas em projecto participando na sua resolução. Isto quer dizer que devem tentar equilibrar o que vão lendo e ouvindo, com o que vão fazendo.&lt;br /&gt;&lt;br /&gt;Com isto, espero ter ajudado alguém a iniciar-se no tema. Comentários, dúvidas e/ou sugestões, just say it.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Verdana" size="2"&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;font face="Verdana" size="2"&gt;[Cross-Posted de &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"&gt;http://www.arquitecturadesoftware.org/blogs/antoniocruz&lt;/a&gt;]&lt;/font&gt; &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p><font face="Verdana" size="2">Por eventualmente ser de interesse para quem pretende iniciar o estudo do WCF, resolvi fazer este post. A ideia é identificar quais são os requisitos desejáveis para serem WCF starters e, de seguida, apresentar alguns recursos que considero de qualidade para quem deseja aprofundar conhecimentos na matéria:</font></p>
<p><strong><font face="Verdana" size="2">Requisitos: </font></strong></p>
<p><font face="Verdana" size="2">- Programação em .NET, especialmente componentes, usando interfaces, atributos, genéricos, threading, herança e transacções. <br />- Bons conhecimentos de arquitecturas distribuídas, em especial usando web services e/ou remoting e queuing, WSE e/ou .ASMX, COM e/ou DCOM.<br />- Conhecimentos dos core standards usados em web services: REST, JSON, XML, XML Namespaces, XML Schemas, WSDL, WS-Addressing.<br />- Conhecimentos funcionais de standards WS-*, particularmente WS-Security, WS-Reliable Messaging, WS-Transactions e WS-Trust.<br />- Compreensão de conceitos ligados a SOA: Orientação a Serviços, Messaging, Concorrência, Transacções Distribuídas, P2P, Federação, Single Sign-On.<br />- Familiaridade com design patterns como proxy, broker, publish-subscriber, data transfer object, adapter, façade e singleton.<br />- Muita vontade de aprender a usar a software factory template para desenvolvimento de serviços mais avançada que existe.</font></p>
<p><font face="Verdana"><font size="2"><strong>Recursos</strong>:</font></font></p>
<p><font face="Verdana" size="2">- Windows Communication Foundation Hands-On, Craig McMurtry, SAMS, 0672328771. Este livro é bastante acessível para quem começar a ler os primeiros textos sobre WCF. Não sendo exaustivo em nenhum tópico, apresenta o mérito de incluir um pouco de informação sobre cada tema relacionado com esta tecnologia, diversidade esta que nem sempre encontrei em outras fontes: P2P, CardSpace, Federação, REST, Custom Behaviors, Custom Transports, etc.<br />- Programming WCF Services, Juval Löwy, O'Reilly Media, 0596526997. Ainda só disponível em "Rough Cuts" na O'Reilly, este é provavelmente o melhor livro disponível até à data. Bastante orientado a aspectos práticos e com muitos exemplos de código reutilizável em projecto. A não perder: todos os exemplos de código disponível no site IDesign.net. Não comecem a desenvolver/testar uma nova funcionalidade a partir do zero, i. é, sem procurar se existe já um exemplo feito. Usando um exemplo como template temos acesso a um excelente ramp-up.<br />- Windows SDK. Disponibilidade obrigatória como Programmer's Reference no dia-a-dia.<br />- </font><a class="" title="wcf.netfx3.com" href="http://wcf.netfx3.com/" target="_blank" mce_href="http://wcf.netfx3.com/"><font face="Verdana" size="2">http://wcf.netfx3.com/</font></a><font face="Verdana" size="2">. Site da comunidade de WCF. Aqui temos acesso a apresentações, artigos, vídeos, webcasts, podcasts, exemplos de código e até acesso a fazer um Hands-On Labs on-line. Aqui, sugiro começarem por ler os whitepapers referidos e depois ver alguns videos, por exemplo.<br />- </font><a class="" title="WCF Forum" href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=118&amp;SiteID=1" target="_blank" mce_href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=118&amp;SiteID=1"><font face="Verdana" size="2">WCF Forum</font></a><font face="Verdana" size="2">. Este é o forum a ter em conta sobre WCF. Seguido atentamente por elementos da equipa de desenvolvimento, é fácil colocar uma dúvida que seja respondida rapidamente.<br />- Finalmente, o recurso mais importante: nós próprios! Não há *nada* que substitua a experimentação sucessiva e metódica das features e o passar por problemas em projecto participando na sua resolução. Isto quer dizer que devem tentar equilibrar o que vão lendo e ouvindo, com o que vão fazendo.<br /><br />Com isto, espero ter ajudado alguém a iniciar-se no tema. Comentários, dúvidas e/ou sugestões, just say it.</font></p>
<p><font face="Verdana" size="2"><font face="Times New Roman" size="3"><font face="Verdana" size="2">[Cross-Posted de <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz">http://www.arquitecturadesoftware.org/blogs/antoniocruz</a>]</font> <br /></font></font></p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>Script#</title><link>http://weblogs.pontonetpt.com/logus2k/posts/8745.aspx</link><pubDate>Fri, 18 Aug 2006 21:39:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/8745.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/8745.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/8745.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/8745.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=8745</trackback:ping><description>&lt;p&gt;Hmm, isto promete:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://projects.nikhilk.net/Projects/ScriptSharp.aspx"&gt;http://projects.nikhilk.net/Projects/ScriptSharp.aspx&lt;/a&gt;&lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Hmm, isto promete:</p>
<p><a href="http://projects.nikhilk.net/Projects/ScriptSharp.aspx">http://projects.nikhilk.net/Projects/ScriptSharp.aspx</a></p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>XML2XSD</title><link>http://weblogs.pontonetpt.com/logus2k/posts/8676.aspx</link><pubDate>Fri, 04 Aug 2006 09:09:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/8676.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/8676.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/8676.aspx#feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/8676.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=8676</trackback:ping><description>&lt;p&gt;Recentemente necessitei de uma forma de gerar um XML Schema a partir de um ficheiro de XML. A ideia é poupar as pessoas de terem que fazer os XML Schemas desde o início, principalmente quado já têm um XML de exemplo e agora só necessitam de gerar o Schema correspondente. É de facto mais fácil e rápido começar por um XML Schema gerado a partir do XML, servindo como base e dessa forma só teremos que o alterar com o que pretendemos.&lt;/p&gt;
&lt;p&gt;Em .NET, há várias ferramentas que fazem essa tarefa, incluindo o próprio Visual Studio, o utilitário XSD.exe que vem no SDK de .NET ou até no site &lt;a href="http://www.gotdotnet.com/"&gt;gotdotnet.com&lt;/a&gt; também existe disponível para download uma aplicação de consola chamada &lt;a href="http://download.microsoft.com/download/8/0/f/80fca9f1-292e-4b50-b512-ccf004d4b58e/xsdinference.exe"&gt;Microsoft XSD Inference 1.0&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;No entanto, o que necessitava era uma forma de disponibilizar esta funcionalidade a qualquer pessoa, em qualquer plataforma (Linux/Perl, Windows/Java, etc), e de preferência, usando uma aplicação browser-based, de modo a não ser necessário instalar qualquer aplicação, runtime, etc.&lt;/p&gt;
&lt;p&gt;Usando a nova classe &lt;a href="http://msdn2.microsoft.com/en-us/library/system.xml.schema.xmlschemainference.aspx"&gt;XmlSchemaInference&lt;/a&gt; da versão 2.0 do .NET Framework, foi fácil implementar a dita aplicação.&lt;/p&gt;
&lt;p&gt;Para quem estiver interessado, aqui fica o source do .aspx e do respectivo code-behind:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font size="2"&gt;
&lt;p&gt;&amp;lt;%&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;@&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#800000" size="2"&gt;Page&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;Language&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="C#"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;ValidateRequest&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="false"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;EnableViewState&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="false"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;AutoEventWireup&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="true"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;CodeFile&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="XML2XSD.aspx.cs"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;Inherits&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="XML2XSD"&lt;/font&gt;&lt;font size="2"&gt; %&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;!&lt;/font&gt;&lt;font color="#800000" size="2"&gt;DOCTYPE&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;html&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;PUBLIC&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;html&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;xmlns&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br /&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;head&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;runat&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="server"&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;title&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;/font&gt;&lt;font size="2"&gt;XML2XSD&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;title&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;style&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;type&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="text/css"&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;body&lt;/font&gt;&lt;font size="2"&gt; {&lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;background-color&lt;/font&gt;&lt;font size="2"&gt;: &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;#eee&lt;/font&gt;&lt;font size="2"&gt;; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;font&lt;/font&gt;&lt;font size="2"&gt;: &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;0.8em&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;Verdana,&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;Arial,&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;Helvetica&lt;/font&gt;&lt;font size="2"&gt;;}&lt;br /&gt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;textarea&lt;/font&gt;&lt;font size="2"&gt; {&lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;border&lt;/font&gt;&lt;font size="2"&gt;: &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;solid&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;1px&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;#000&lt;/font&gt;&lt;font size="2"&gt;;}&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;style&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;head&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;body&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;form&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;id&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="form1"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;runat&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="server"&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;div&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;center&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;asp&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;:&lt;/font&gt;&lt;font color="#800000" size="2"&gt;Label&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;ID&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="Message"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;runat&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="server"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;/&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;div&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;/font&gt;&lt;font size="2"&gt;Paste your XML here and click &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;asp&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;:&lt;/font&gt;&lt;font color="#800000" size="2"&gt;Button&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;ID&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="Submit"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;Text&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="Deduce Schema(s)"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;runat&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="server"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;/&amp;gt;&lt;/font&gt;&lt;font size="2"&gt; to generate the corresponding XML Schema(s):&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;div&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;p&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;asp&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;:&lt;/font&gt;&lt;font color="#800000" size="2"&gt;TextBox&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;ID&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="XML"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;Rows&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="20"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;Columns&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="80"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;TextMode&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="MultiLine"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;runat&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="server"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;/&amp;gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;p&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;p&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;asp&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;:&lt;/font&gt;&lt;font color="#800000" size="2"&gt;PlaceHolder&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;ID&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="XSDContent"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;runat&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="server"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;EnableViewState&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;="false"&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;/&amp;gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;p&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;center&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;div&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;form&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;body&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000" size="2"&gt;html&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.IO;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Text;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Web;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Web.UI;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Web.UI.WebControls;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Web.UI.HtmlControls;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Xml;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000000"&gt; System.Xml.Schema;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;partial&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;class&lt;/font&gt;&lt;font color="#000000" size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;XML2XSD&lt;/font&gt;&lt;font color="#000000" size="2"&gt; : &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Page&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;{&lt;br /&gt;    &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;protected&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;void&lt;/font&gt;&lt;font size="2"&gt; Page_Load(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;object&lt;/font&gt;&lt;font size="2"&gt; sender, &lt;/font&gt;&lt;font color="#008080" size="2"&gt;EventArgs&lt;/font&gt;&lt;font size="2"&gt; e)&lt;br /&gt;    &lt;/font&gt;&lt;font size="2"&gt;{&lt;br /&gt;         &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;if&lt;/font&gt;&lt;font size="2"&gt; (XML.Text.Length &amp;gt; 0)&lt;br /&gt;        &lt;/font&gt;&lt;font size="2"&gt;{&lt;br /&gt;             &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#008080" size="2"&gt;MemoryStream&lt;/font&gt;&lt;font size="2"&gt; inputStream = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;MemoryStream&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#008080" size="2"&gt;Encoding&lt;/font&gt;&lt;font size="2"&gt;.UTF8.GetBytes(XML.Text)))&lt;br /&gt;            &lt;/font&gt;&lt;font size="2"&gt;{&lt;br /&gt;                 &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlReader&lt;/font&gt;&lt;font size="2"&gt; xmlReader = &lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlReader&lt;/font&gt;&lt;font size="2"&gt;.Create(inputStream))&lt;br /&gt;                {&lt;br /&gt;                     &lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlSchemaInference&lt;/font&gt;&lt;font size="2"&gt; xsdi = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlSchemaInference&lt;/font&gt;&lt;font size="2"&gt;();&lt;br /&gt;                     &lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlSchemaSet&lt;/font&gt;&lt;font size="2"&gt; schemaSet = xsdi.InferSchema(xmlReader);&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;                     XSDContent.Controls.Clear();&lt;br /&gt;                     &lt;/font&gt;&lt;font color="#008080" size="2"&gt;HtmlGenericControl&lt;/font&gt;&lt;font size="2"&gt; textArea = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;font size="2"&gt;;&lt;br /&gt;&lt;br /&gt;                     &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;foreach&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlSchema&lt;/font&gt;&lt;font size="2"&gt; schema &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;in&lt;/font&gt;&lt;font size="2"&gt; schemaSet.Schemas())&lt;br /&gt;                    {&lt;br /&gt;                         &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#008080" size="2"&gt;MemoryStream&lt;/font&gt;&lt;font size="2"&gt; outputStream = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;MemoryStream&lt;/font&gt;&lt;font size="2"&gt;())&lt;br /&gt;                         {&lt;br /&gt;                              &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlTextWriter&lt;/font&gt;&lt;font size="2"&gt; xmlWriter = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;XmlTextWriter&lt;/font&gt;&lt;font size="2"&gt;(outputStream, &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Encoding&lt;/font&gt;&lt;font size="2"&gt;.UTF8))&lt;br /&gt;                              {&lt;br /&gt;                                   xmlWriter.Formatting = &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Formatting&lt;/font&gt;&lt;font size="2"&gt;.Indented;&lt;br /&gt;                                   schema.Write(xmlWriter);&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;                                   outputStream.Position = 0;&lt;br /&gt;&lt;br /&gt;                                   &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#008080" size="2"&gt;StreamReader&lt;/font&gt;&lt;font size="2"&gt; streamReader = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;StreamReader&lt;/font&gt;&lt;font size="2"&gt;(outputStream, &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;true&lt;/font&gt;&lt;font size="2"&gt;))&lt;br /&gt;                                   {&lt;br /&gt;                                        &lt;/font&gt;&lt;font size="2"&gt;textArea = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;HtmlGenericControl&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"textarea"&lt;/font&gt;&lt;font size="2"&gt;);&lt;br /&gt;                                        textArea.Attributes.Add(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"rows"&lt;/font&gt;&lt;font size="2"&gt;, &lt;/font&gt;&lt;font color="#800000" size="2"&gt;"20"&lt;/font&gt;&lt;font size="2"&gt;);&lt;br /&gt;                                        textArea.Attributes.Add(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"cols"&lt;/font&gt;&lt;font size="2"&gt;, &lt;/font&gt;&lt;font color="#800000" size="2"&gt;"80"&lt;/font&gt;&lt;font size="2"&gt;);&lt;br /&gt;                                        textArea.InnerText = streamReader.ReadToEnd();&lt;br /&gt;                                        XSDContent.Controls.Add(textArea);&lt;br /&gt;&lt;br /&gt;                                        &lt;/font&gt;&lt;font size="2"&gt;streamReader.Close();&lt;br /&gt;                                   }&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;br /&gt;                                   xmlWriter.Close();&lt;br /&gt;                               }&lt;br /&gt;&lt;br /&gt;                               outputStream.Close();&lt;br /&gt;                           }&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;                       }&lt;br /&gt;&lt;br /&gt;                       xmlReader.Close();&lt;br /&gt;                   }&lt;br /&gt;&lt;br /&gt;                   inputStream.Close();&lt;br /&gt;               }&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;           }&lt;br /&gt;      }&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;&lt;/font&gt; &lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Recentemente necessitei de uma forma de gerar um XML Schema a partir de um ficheiro de XML. A ideia é poupar as pessoas de terem que fazer os XML Schemas desde o início, principalmente quado já têm um XML de exemplo e agora só necessitam de gerar o Schema correspondente. É de facto mais fácil e rápido começar por um XML Schema gerado a partir do XML, servindo como base e dessa forma só teremos que o alterar com o que pretendemos.</p>
<p>Em .NET, há várias ferramentas que fazem essa tarefa, incluindo o próprio Visual Studio, o utilitário XSD.exe que vem no SDK de .NET ou até no site <a href="http://www.gotdotnet.com/">gotdotnet.com</a> também existe disponível para download uma aplicação de consola chamada <a href="http://download.microsoft.com/download/8/0/f/80fca9f1-292e-4b50-b512-ccf004d4b58e/xsdinference.exe">Microsoft XSD Inference 1.0</a>. </p>
<p>No entanto, o que necessitava era uma forma de disponibilizar esta funcionalidade a qualquer pessoa, em qualquer plataforma (Linux/Perl, Windows/Java, etc), e de preferência, usando uma aplicação browser-based, de modo a não ser necessário instalar qualquer aplicação, runtime, etc.</p>
<p>Usando a nova classe <a href="http://msdn2.microsoft.com/en-us/library/system.xml.schema.xmlschemainference.aspx">XmlSchemaInference</a> da versão 2.0 do .NET Framework, foi fácil implementar a dita aplicação.</p>
<p>Para quem estiver interessado, aqui fica o source do .aspx e do respectivo code-behind:</p><font size="2">
<p></p></font><font color="#0000ff" size="2"><font size="2">
<p>&lt;%</p></font><font color="#0000ff" size="2">@</font><font size="2"> </font><font color="#800000" size="2">Page</font><font size="2"> </font><font color="#ff0000" size="2">Language</font><font color="#0000ff" size="2">="C#"</font><font size="2"> </font><font color="#ff0000" size="2">ValidateRequest</font><font color="#0000ff" size="2">="false"</font><font size="2"> </font><font color="#ff0000" size="2">EnableViewState</font><font color="#0000ff" size="2">="false"</font><font size="2"> </font><font color="#ff0000" size="2">AutoEventWireup</font><font color="#0000ff" size="2">="true"</font><font size="2"> </font><font color="#ff0000" size="2">CodeFile</font><font color="#0000ff" size="2">="XML2XSD.aspx.cs"</font><font size="2"> </font><font color="#ff0000" size="2">Inherits</font><font color="#0000ff" size="2">="XML2XSD"</font><font size="2"> %&gt;<br /></font><font color="#0000ff" size="2">&lt;!</font><font color="#800000" size="2">DOCTYPE</font><font color="#000000" size="2"> </font><font color="#ff0000" size="2">html</font><font color="#000000" size="2"> </font><font color="#ff0000" size="2">PUBLIC</font><font color="#000000" size="2"> </font><font color="#0000ff" size="2">"-//W3C//DTD XHTML 1.0 Transitional//EN"</font><font color="#000000" size="2"> </font><font color="#0000ff" size="2">"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br />&lt;</font><font color="#800000" size="2">html</font><font color="#000000" size="2"> </font><font color="#ff0000" size="2">xmlns</font><font color="#0000ff" size="2">="http://www.w3.org/1999/xhtml"&gt;<br />&lt;</font><font color="#800000" size="2">head</font><font color="#000000" size="2"> </font><font color="#ff0000" size="2">runat</font><font color="#0000ff" size="2">="server"&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">title</font><font color="#0000ff" size="2">&gt;</font><font size="2">XML2XSD</font><font color="#0000ff" size="2">&lt;/</font><font color="#800000" size="2">title</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">style</font><font size="2"> </font><font color="#ff0000" size="2">type</font><font color="#0000ff" size="2">="text/css"&gt;<br /></font><font color="#800000" size="2">body</font><font size="2"> {</font><font color="#ff0000" size="2">background-color</font><font size="2">: </font><font color="#0000ff" size="2">#eee</font><font size="2">; </font><font color="#ff0000" size="2">font</font><font size="2">: </font><font color="#0000ff" size="2">0.8em</font><font size="2"> </font><font color="#0000ff" size="2">Verdana,</font><font size="2"> </font><font color="#0000ff" size="2">Arial,</font><font size="2"> </font><font color="#0000ff" size="2">Helvetica</font><font size="2">;}<br /></font><font color="#800000" size="2">textarea</font><font size="2"> {</font><font color="#ff0000" size="2">border</font><font size="2">: </font><font color="#0000ff" size="2">solid</font><font size="2"> </font><font color="#0000ff" size="2">1px</font><font size="2"> </font><font color="#0000ff" size="2">#000</font><font size="2">;}<br /></font><font color="#0000ff" size="2">&lt;/</font><font color="#800000" size="2">style</font><font color="#0000ff" size="2">&gt;<br />&lt;/</font><font color="#800000" size="2">head</font><font color="#0000ff" size="2">&gt;<br />&lt;</font><font color="#800000" size="2">body</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">form</font><font size="2"> </font><font color="#ff0000" size="2">id</font><font color="#0000ff" size="2">="form1"</font><font size="2"> </font><font color="#ff0000" size="2">runat</font><font color="#0000ff" size="2">="server"&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">div</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">center</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">asp</font><font color="#0000ff" size="2">:</font><font color="#800000" size="2">Label</font><font size="2"> </font><font color="#ff0000" size="2">ID</font><font color="#0000ff" size="2">="Message"</font><font size="2"> </font><font color="#ff0000" size="2">runat</font><font color="#0000ff" size="2">="server"</font><font size="2"> </font><font color="#0000ff" size="2">/&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">div</font><font color="#0000ff" size="2">&gt;</font><font size="2">Paste your XML here and click </font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">asp</font><font color="#0000ff" size="2">:</font><font color="#800000" size="2">Button</font><font size="2"> </font><font color="#ff0000" size="2">ID</font><font color="#0000ff" size="2">="Submit"</font><font size="2"> </font><font color="#ff0000" size="2">Text</font><font color="#0000ff" size="2">="Deduce Schema(s)"</font><font size="2"> </font><font color="#ff0000" size="2">runat</font><font color="#0000ff" size="2">="server"</font><font size="2"> </font><font color="#0000ff" size="2">/&gt;</font><font size="2"> to generate the corresponding XML Schema(s):</font><font color="#0000ff" size="2">&lt;/</font><font color="#800000" size="2">div</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">p</font><font color="#0000ff" size="2">&gt;&lt;</font><font color="#800000" size="2">asp</font><font color="#0000ff" size="2">:</font><font color="#800000" size="2">TextBox</font><font size="2"> </font><font color="#ff0000" size="2">ID</font><font color="#0000ff" size="2">="XML"</font><font size="2"> </font><font color="#ff0000" size="2">Rows</font><font color="#0000ff" size="2">="20"</font><font size="2"> </font><font color="#ff0000" size="2">Columns</font><font color="#0000ff" size="2">="80"</font><font size="2"> </font><font color="#ff0000" size="2">TextMode</font><font color="#0000ff" size="2">="MultiLine"</font><font size="2"> </font><font color="#ff0000" size="2">runat</font><font color="#0000ff" size="2">="server"</font><font size="2"> </font><font color="#0000ff" size="2">/&gt;&lt;/</font><font color="#800000" size="2">p</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;</font><font color="#800000" size="2">p</font><font color="#0000ff" size="2">&gt;&lt;</font><font color="#800000" size="2">asp</font><font color="#0000ff" size="2">:</font><font color="#800000" size="2">PlaceHolder</font><font size="2"> </font><font color="#ff0000" size="2">ID</font><font color="#0000ff" size="2">="XSDContent"</font><font size="2"> </font><font color="#ff0000" size="2">runat</font><font color="#0000ff" size="2">="server"</font><font size="2"> </font><font color="#ff0000" size="2">EnableViewState</font><font color="#0000ff" size="2">="false"</font><font size="2"> </font><font color="#0000ff" size="2">/&gt;&lt;/</font><font color="#800000" size="2">p</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;/</font><font color="#800000" size="2">center</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;/</font><font color="#800000" size="2">div</font><font color="#0000ff" size="2">&gt;<br /></font><font color="#0000ff" size="2">&lt;/</font><font color="#800000" size="2">form</font><font color="#0000ff" size="2">&gt;<br />&lt;/</font><font color="#800000" size="2">body</font><font color="#0000ff" size="2">&gt;<br />&lt;/</font><font color="#800000" size="2">html</font><font color="#0000ff" size="2">&gt;</font></font>
<p><font color="#0000ff" size="2"><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.IO;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Text;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Web;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Web.UI;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Web.UI.WebControls;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Web.UI.HtmlControls;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Xml;<br /></font></font><font color="#0000ff" size="2">using</font><font size="2"><font color="#000000"> System.Xml.Schema;</font></font></font></p>
<p><font color="#0000ff" size="2">public</font><font color="#000000" size="2"> </font><font color="#0000ff" size="2">partial</font><font color="#000000" size="2"> </font><font color="#0000ff" size="2">class</font><font color="#000000" size="2"> </font><font color="#008080" size="2">XML2XSD</font><font color="#000000" size="2"> : </font><font color="#008080" size="2">Page<br /></font><font size="2">{<br />    </font><font color="#0000ff" size="2">protected</font><font size="2"> </font><font color="#0000ff" size="2">void</font><font size="2"> Page_Load(</font><font color="#0000ff" size="2">object</font><font size="2"> sender, </font><font color="#008080" size="2">EventArgs</font><font size="2"> e)<br />    </font><font size="2">{<br />         </font><font color="#0000ff" size="2">if</font><font size="2"> (XML.Text.Length &gt; 0)<br />        </font><font size="2">{<br />             </font><font color="#0000ff" size="2">using</font><font size="2"> (</font><font color="#008080" size="2">MemoryStream</font><font size="2"> inputStream = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">MemoryStream</font><font size="2">(</font><font color="#008080" size="2">Encoding</font><font size="2">.UTF8.GetBytes(XML.Text)))<br />            </font><font size="2">{<br />                 </font><font color="#0000ff" size="2">using</font><font size="2"> (</font><font color="#008080" size="2">XmlReader</font><font size="2"> xmlReader = </font><font color="#008080" size="2">XmlReader</font><font size="2">.Create(inputStream))<br />                {<br />                     </font><font color="#008080" size="2">XmlSchemaInference</font><font size="2"> xsdi = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">XmlSchemaInference</font><font size="2">();<br />                     </font><font color="#008080" size="2">XmlSchemaSet</font><font size="2"> schemaSet = xsdi.InferSchema(xmlReader);<br /><br /></font><font size="2">                     XSDContent.Controls.Clear();<br />                     </font><font color="#008080" size="2">HtmlGenericControl</font><font size="2"> textArea = </font><font color="#0000ff" size="2">null</font><font size="2">;<br /><br />                     </font><font color="#0000ff" size="2">foreach</font><font size="2"> (</font><font color="#008080" size="2">XmlSchema</font><font size="2"> schema </font><font color="#0000ff" size="2">in</font><font size="2"> schemaSet.Schemas())<br />                    {<br />                         </font><font color="#0000ff" size="2">using</font><font size="2"> (</font><font color="#008080" size="2">MemoryStream</font><font size="2"> outputStream = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">MemoryStream</font><font size="2">())<br />                         {<br />                              </font><font color="#0000ff" size="2">using</font><font size="2"> (</font><font color="#008080" size="2">XmlTextWriter</font><font size="2"> xmlWriter = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">XmlTextWriter</font><font size="2">(outputStream, </font><font color="#008080" size="2">Encoding</font><font size="2">.UTF8))<br />                              {<br />                                   xmlWriter.Formatting = </font><font color="#008080" size="2">Formatting</font><font size="2">.Indented;<br />                                   schema.Write(xmlWriter);<br /></font><font size="2">                                   outputStream.Position = 0;<br /><br />                                   </font><font color="#0000ff" size="2">using</font><font size="2"> (</font><font color="#008080" size="2">StreamReader</font><font size="2"> streamReader = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">StreamReader</font><font size="2">(outputStream, </font><font color="#0000ff" size="2">true</font><font size="2">))<br />                                   {<br />                                        </font><font size="2">textArea = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">HtmlGenericControl</font><font size="2">(</font><font color="#800000" size="2">"textarea"</font><font size="2">);<br />                                        textArea.Attributes.Add(</font><font color="#800000" size="2">"rows"</font><font size="2">, </font><font color="#800000" size="2">"20"</font><font size="2">);<br />                                        textArea.Attributes.Add(</font><font color="#800000" size="2">"cols"</font><font size="2">, </font><font color="#800000" size="2">"80"</font><font size="2">);<br />                                        textArea.InnerText = streamReader.ReadToEnd();<br />                                        XSDContent.Controls.Add(textArea);<br /><br />                                        </font><font size="2">streamReader.Close();<br />                                   }<br /></font><font size="2"><br />                                   xmlWriter.Close();<br />                               }<br /><br />                               outputStream.Close();<br />                           }<br /></font><font size="2">                       }<br /><br />                       xmlReader.Close();<br />                   }<br /><br />                   inputStream.Close();<br />               }<br /></font><font size="2">           }<br />      }<br />}</font></p>
<p><font color="#0000ff" size="2"></font> </p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>JSON Power(ed) II</title><link>http://weblogs.pontonetpt.com/logus2k/posts/8641.aspx</link><pubDate>Tue, 01 Aug 2006 11:07:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/8641.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/8641.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/8641.aspx#feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/8641.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=8641</trackback:ping><description>&lt;p&gt;Há já algum tempo que penso nas implicações do uso das técnicas denominadas de AJAX nas arquitecturas service-oriented. Neste post, vou partilhar alguma da experiência conseguida entretanto. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cenário&lt;/strong&gt;: Necessitamos de pesquisar a base de dados de uma aplicação já em produção de forma a apresentarmos a informação com HTML, num browser. A aplicação apenas disponibiliza feeds de RSS, permitindo pesquisar a base de dados e paginar os resultados mediante parâmetros em querystring. Não é viável proceder a alterações na aplicação pelo que se prefere uma solução que não implique fazer alterações ao código existente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solução&lt;/strong&gt;: &lt;/p&gt;
&lt;p&gt;a) Usar o HTML DOM para navegar o XML do RSS e ir construindo dinamicamente os elementos e atributos de HTML de que necessitamos para apresentar a informação. Apesar de dar bastante trabalho, esta abordagem tem a vantagem de ser cross-browser e não possuir dependências externas;&lt;/p&gt;
&lt;p&gt;b) Usar XSLT em client-side (fazendo transformações no browser). Recorrendo a uma livraria como a &lt;a href="http://sarissa.sourceforge.net/doc/overview-summary.html"&gt;Sarissa&lt;/a&gt;, será fácil transformar em HTML os RSS devolvidos pelo servidor. Também é possível usar o XSL para transformarmos o RSS em JSON (e a partir daí construír a apresentação). &lt;a href="https://json-xslt.codebase.ebay.com/"&gt;Este .xsl&lt;/a&gt; faz uma transformação genérica de XML para JSON, embora eu tenha detectado problemas com atributos e aparentemente as secções de CDATA não são suportadas;&lt;/p&gt;
&lt;p&gt;c) Usar um broker, isto é, uma aplicação server-side que receba os pedidos que se destinam à aplicação de RSS e faça forward destes para essa aplicação. Porque todos os pedidos (e respectivas respostas) passam pelo broker, é fácil proceder à transformação das respostas em HTML (ou outro formato).&lt;/p&gt;
&lt;p&gt;Na minha opinião, a melhor hipótese é a c). Aqui ficam as razões da escolha:&lt;/p&gt;
&lt;p&gt;- O uso do &lt;a href="http://patternshare.org/default.aspx/Home.PP.Broker"&gt;padrão de brokering&lt;/a&gt; é pelo menos bastante recomendado (pessoalmente, acho obrigatório) em arquitecturas service-oriented. O &lt;em&gt;decoupling&lt;/em&gt; decorrente da "intercepção" dos pedidos é só por si, razão suficiente para justificar a sua adopção, mas muitas outras vantagens são obtidas a partir da sua implementação.&lt;/p&gt;
&lt;p&gt;- Embora não comparável ao leque de serviços oferecido por um &lt;a href="http://en.wikipedia.org/wiki/Enterprise_Service_Bus"&gt;ESB&lt;/a&gt;, um broker simples traz a vantagem de que tanto os clientes como os serviços não têm de se preocupar com os formatos dos respectivos pedidos e respostas: o problema das traduções pode sempre ficar a cargo do broker (v. o resto da solução).&lt;/p&gt;
&lt;p&gt;Assumindo que optámos pelo broker, enuncio mais algumas hipóteses:&lt;/p&gt;
&lt;p&gt;a) Usar um elemento de &amp;lt;script&amp;gt; estático que incluímos na página, cuja propriedade &lt;em&gt;src&lt;/em&gt; aponta para o broker. O broker pode fazer a transformação do RSS para JSON usando qualquer linguagem em server-side (não precisa de ser XSLT, pode ser C#, Java, PHP, etc.). Para um exemplo de código que produz JSON a partir de XML usando C#, podem ver &lt;a href="http://www.phdcc.com/xml2json.htm"&gt;aqui&lt;/a&gt;. O único problema que até agora encontrei neste código foi o facto de (também) não suportar CDATA. Mas foi simples fazer uma alteração para suportar esse elemento e neste momento tenho uma versão que suporta CDATA, atributos, arrays, etc. (se alguém estiver interessado nesta versão basta fazer um post).&lt;/p&gt;
&lt;p&gt;b) Usar o objecto HTTPRequest para fazer o pedido, embora neste caso ficamos sujeitos às &lt;a href="http://developer.yahoo.com/javascript/howto-proxy.html#why"&gt;restrições de pedidos cross-domain&lt;/a&gt; (a propósito, acho que devia chamar-se &lt;em&gt;cross-server&lt;/em&gt;, porque não basta estarmos no mesmo domínio para funcionar). Uma solução para isto (mais uma vez) usar um broker no mesmo servidor da aplicação. Esta abordagem tem apenas o problema de termos que ter um broker a fazer de &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Reverse_proxy"&gt;reverse proxy&lt;/a&gt;&lt;/em&gt; em cada uma das aplicações que pretendemos consumir (caso fossem várias);&lt;/p&gt;
&lt;p&gt;c) Usar um elemento &amp;lt;script&amp;gt;, tal como descrito em a), mas criado dinamicamente, usando o HTML DOM. Para um exemplo da criação dinâmica, podem consultar &lt;a href="http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html"&gt;este artigo&lt;/a&gt;. De notar que também neste caso é um pressuposto que o JSON seja criado no servidor;&lt;/p&gt;
&lt;p&gt;d) Para os casos em que hajam &lt;em&gt;muitos&lt;/em&gt; pedidos concorrentes ao servidor, o facto de serem feitas transformações de XML para JSON pode revelar-se problemático, devido ao &lt;em&gt;overhead&lt;/em&gt; introduzido pelas transformações. Neste caso, sugiro usarem a abordagem descrita em c) para devolverem apenas o RSS encapsulado numa propriedade de um objecto de JSON e proceder à sua transformação para JSON, mas no cliente. Vamos ganhar com isto que a carga das transformações de XML para JSON são distribuídas por cada cliente, ficando o broker com a carga mínima de criar uma string que apenas contém o RSS pretendido. Para uma implementação de conversões entre XML e JSON usando JavaScript, podem ver &lt;a href="http://goessner.net/download/prj/jsonxml/"&gt;aqui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Face ao exposto, considerem que em alguns casos, não faz grande sentido desenvolvermos XML Web Services que sejam compatíveis com o &lt;a href="http://www.ws-i.org/Profiles/BasicProfile-1.1.html"&gt;Basic Profile 1.1&lt;/a&gt; da &lt;a href="http://www.ws-i.org/"&gt;WS-I&lt;/a&gt;, etc. Se a complexidade de o fazer é superior ao benefício alcançado, então a melhor opção pode encontrar-se num mero... RSS (no entanto, a opção de usar JSON em vez de XML também traz várias condicionantes conhecidas como ausência de schema que permita a validação das mensagens, ausência de contrato automatizável como o WSDL, etc.).&lt;/p&gt;
&lt;p&gt;Penso que a abordagem descrita em d) condensa a melhor abordagem possível em termos da arquitectura Web 2.0 num cenário SOA, conforme o que ficou descrito. Também penso ter demonstrado o interesse (e actualidade) de pensarmos em que termos a Web 2.0 condiciona/potencia as arquitecturas service-oriented e a arquitectura de software de um modo geral.&lt;/p&gt;
&lt;p&gt;[Cross-Posted de &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"&gt;http://www.arquitecturadesoftware.org/blogs/antoniocruz&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Há já algum tempo que penso nas implicações do uso das técnicas denominadas de AJAX nas arquitecturas service-oriented. Neste post, vou partilhar alguma da experiência conseguida entretanto. </p>
<p><strong>Cenário</strong>: Necessitamos de pesquisar a base de dados de uma aplicação já em produção de forma a apresentarmos a informação com HTML, num browser. A aplicação apenas disponibiliza feeds de RSS, permitindo pesquisar a base de dados e paginar os resultados mediante parâmetros em querystring. Não é viável proceder a alterações na aplicação pelo que se prefere uma solução que não implique fazer alterações ao código existente.</p>
<p><strong>Solução</strong>: </p>
<p>a) Usar o HTML DOM para navegar o XML do RSS e ir construindo dinamicamente os elementos e atributos de HTML de que necessitamos para apresentar a informação. Apesar de dar bastante trabalho, esta abordagem tem a vantagem de ser cross-browser e não possuir dependências externas;</p>
<p>b) Usar XSLT em client-side (fazendo transformações no browser). Recorrendo a uma livraria como a <a href="http://sarissa.sourceforge.net/doc/overview-summary.html">Sarissa</a>, será fácil transformar em HTML os RSS devolvidos pelo servidor. Também é possível usar o XSL para transformarmos o RSS em JSON (e a partir daí construír a apresentação). <a href="https://json-xslt.codebase.ebay.com/">Este .xsl</a> faz uma transformação genérica de XML para JSON, embora eu tenha detectado problemas com atributos e aparentemente as secções de CDATA não são suportadas;</p>
<p>c) Usar um broker, isto é, uma aplicação server-side que receba os pedidos que se destinam à aplicação de RSS e faça forward destes para essa aplicação. Porque todos os pedidos (e respectivas respostas) passam pelo broker, é fácil proceder à transformação das respostas em HTML (ou outro formato).</p>
<p>Na minha opinião, a melhor hipótese é a c). Aqui ficam as razões da escolha:</p>
<p>- O uso do <a href="http://patternshare.org/default.aspx/Home.PP.Broker">padrão de brokering</a> é pelo menos bastante recomendado (pessoalmente, acho obrigatório) em arquitecturas service-oriented. O <em>decoupling</em> decorrente da "intercepção" dos pedidos é só por si, razão suficiente para justificar a sua adopção, mas muitas outras vantagens são obtidas a partir da sua implementação.</p>
<p>- Embora não comparável ao leque de serviços oferecido por um <a href="http://en.wikipedia.org/wiki/Enterprise_Service_Bus">ESB</a>, um broker simples traz a vantagem de que tanto os clientes como os serviços não têm de se preocupar com os formatos dos respectivos pedidos e respostas: o problema das traduções pode sempre ficar a cargo do broker (v. o resto da solução).</p>
<p>Assumindo que optámos pelo broker, enuncio mais algumas hipóteses:</p>
<p>a) Usar um elemento de &lt;script&gt; estático que incluímos na página, cuja propriedade <em>src</em> aponta para o broker. O broker pode fazer a transformação do RSS para JSON usando qualquer linguagem em server-side (não precisa de ser XSLT, pode ser C#, Java, PHP, etc.). Para um exemplo de código que produz JSON a partir de XML usando C#, podem ver <a href="http://www.phdcc.com/xml2json.htm">aqui</a>. O único problema que até agora encontrei neste código foi o facto de (também) não suportar CDATA. Mas foi simples fazer uma alteração para suportar esse elemento e neste momento tenho uma versão que suporta CDATA, atributos, arrays, etc. (se alguém estiver interessado nesta versão basta fazer um post).</p>
<p>b) Usar o objecto HTTPRequest para fazer o pedido, embora neste caso ficamos sujeitos às <a href="http://developer.yahoo.com/javascript/howto-proxy.html#why">restrições de pedidos cross-domain</a> (a propósito, acho que devia chamar-se <em>cross-server</em>, porque não basta estarmos no mesmo domínio para funcionar). Uma solução para isto (mais uma vez) usar um broker no mesmo servidor da aplicação. Esta abordagem tem apenas o problema de termos que ter um broker a fazer de <em><a href="http://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a></em> em cada uma das aplicações que pretendemos consumir (caso fossem várias);</p>
<p>c) Usar um elemento &lt;script&gt;, tal como descrito em a), mas criado dinamicamente, usando o HTML DOM. Para um exemplo da criação dinâmica, podem consultar <a href="http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html">este artigo</a>. De notar que também neste caso é um pressuposto que o JSON seja criado no servidor;</p>
<p>d) Para os casos em que hajam <em>muitos</em> pedidos concorrentes ao servidor, o facto de serem feitas transformações de XML para JSON pode revelar-se problemático, devido ao <em>overhead</em> introduzido pelas transformações. Neste caso, sugiro usarem a abordagem descrita em c) para devolverem apenas o RSS encapsulado numa propriedade de um objecto de JSON e proceder à sua transformação para JSON, mas no cliente. Vamos ganhar com isto que a carga das transformações de XML para JSON são distribuídas por cada cliente, ficando o broker com a carga mínima de criar uma string que apenas contém o RSS pretendido. Para uma implementação de conversões entre XML e JSON usando JavaScript, podem ver <a href="http://goessner.net/download/prj/jsonxml/">aqui</a>.</p>
<p>Face ao exposto, considerem que em alguns casos, não faz grande sentido desenvolvermos XML Web Services que sejam compatíveis com o <a href="http://www.ws-i.org/Profiles/BasicProfile-1.1.html">Basic Profile 1.1</a> da <a href="http://www.ws-i.org/">WS-I</a>, etc. Se a complexidade de o fazer é superior ao benefício alcançado, então a melhor opção pode encontrar-se num mero... RSS (no entanto, a opção de usar JSON em vez de XML também traz várias condicionantes conhecidas como ausência de schema que permita a validação das mensagens, ausência de contrato automatizável como o WSDL, etc.).</p>
<p>Penso que a abordagem descrita em d) condensa a melhor abordagem possível em termos da arquitectura Web 2.0 num cenário SOA, conforme o que ficou descrito. Também penso ter demonstrado o interesse (e actualidade) de pensarmos em que termos a Web 2.0 condiciona/potencia as arquitecturas service-oriented e a arquitectura de software de um modo geral.</p>
<p>[Cross-Posted de <a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz">http://www.arquitecturadesoftware.org/blogs/antoniocruz</a>]</p>
<p> </p></body></item><item><dc:creator>António José Simões da Cruz</dc:creator><title>JSON Power(ed)</title><link>http://weblogs.pontonetpt.com/logus2k/posts/8626.aspx</link><pubDate>Mon, 31 Jul 2006 22:25:00 GMT</pubDate><guid>http://weblogs.pontonetpt.com/logus2k/posts/8626.aspx</guid><wfw:comment>http://weblogs.pontonetpt.com/logus2k/comments/8626.aspx</wfw:comment><comments>http://weblogs.pontonetpt.com/logus2k/posts/8626.aspx#feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.pontonetpt.com/logus2k/comments/commentRss/8626.aspx</wfw:commentRss><trackback:ping>http://weblogs.pontonetpt.com/logus2k/trackback.aspx?ID=8626</trackback:ping><description>&lt;p&gt;Tenho feito alguns testes com &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; e brevemente espero usá-lo em produção. O JSON tem vindo a ganhar notoriedade e mesmo o &lt;a href="http://atlas.asp.net/"&gt;ATLAS&lt;/a&gt; usa internamente um &lt;a href="http://www.nikhilk.net/AtlasArchitecture.aspx"&gt;JSON Serializer&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Há algum tempo subscrevi o grupo de &lt;a href="http://groups.yahoo.com/group/json/"&gt;JSON&lt;/a&gt; do Yahoo e tenho acompanhado uma discussão interessante sobre a possibilidade (necessidade?) de estender o JSON para suportar a identificação de vários tipos de dados primitivos noutras linguagens, como por exemplo o DateTime e até de alguns tipos de dados complexos, como o &lt;a href="http://groups.yahoo.com/group/json/message/450"&gt;DataSet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Para possibilitar essas features, há até quem proponha usar "tags" no JSON (!) e fazer um Schema que permita validar JSON. E &lt;a href="http://groups.yahoo.com/group/json/message/469"&gt;apesar de solicitado&lt;/a&gt;, o &lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt; não se pronunciou sobre estas questões. Quer dizer, pelo menos até este fim-de-semana, em que &lt;a href="http://groups.yahoo.com/group/json/message/487"&gt;fez um post&lt;/a&gt; (ao que me pareceu deliberadamente lacónico), em que simplesmente anuncia ao newsgroup que &lt;a href="http://www.ietf.org/rfc/rfc4627.txt"&gt;o RFC do JSON foi publicado&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Da mesma forma que outros, não penso que o JSON deva ser estendido para suportar mais tipos de dados, mas concordo que possam haver outras especificações produzidas tendo como base o JSON, sob pena de tornarmos a utilização do JSON confusa pela falta de consistência entre implementações. Sugiro que agora que existe um RFC, vamos usá-lo para basear o nosso desenvolvimento e especialmente, vamos deixar-nos de suspirar pelas funcionalidades que advêm do uso de XML e XML Schemas, que continuam por seu lado a ser evidentemente insubstituíveis no seu contexto. Ou seja, defendo que usemos a ferramenta certa para cada tipo de trabalho.&lt;/p&gt;
&lt;p&gt;[Cross-Posted de &lt;a href="http://www.arquitecturadesoftware.org/blogs/antoniocruz"&gt;http://www.arquitecturadesoftware.org/blogs/antoniocruz&lt;/a&gt;]&lt;/p&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Tenho feito alguns testes com <a href="http://www.json.org/">JSON</a> e brevemente espero usá-lo em produção. O JSON tem vindo a ganhar notoriedade e mesmo o <a href="http://atlas.asp.net/">ATLAS</a> usa internamente um <a href="http://www.nikhilk.net/AtlasArchitecture.aspx">JSON Serializer</a>. </p>
<p>Há algum tempo subscrevi o grupo de <a href="http://groups.yahoo.com/group/json/">JSON</a> do Yahoo e tenho acompanhado uma discussão interessante sobre a possibilidade (necessidade?) de estender o JSON para suportar a identificação de vários tipos de dados primitivos noutras linguagens, como por exemplo o DateTime e até de alguns tipos de dados complexos, como o <a href="http://groups.yahoo.com/group/json/message/450">DataSet</a>.</p>
<p>Para possibilitar essas features, há até quem proponha usar "tags" no JSON (!) e fazer um Schema que permita validar JSON. E <a href="http://groups.yahoo.com/group/json/message/469">apesar de solicitado</a>, o <a href="http://www.crockford.com/">Douglas Crockford</a> não se pronunciou sobre estas questões. Quer dizer, pelo menos até este fim-de-semana, em que <a href="http://groups.yahoo.com/group/json/message/487">fez um post</a> (ao que me pareceu deliberadamente lacónico), em que simplesmente anuncia ao newsgroup que <a href="http://www.ietf.org/rfc/rfc4627.txt">o RFC do JSON foi publicado</a>.</p>