﻿<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>My Technobabble</title>
    <atom:link
      href="https://review.docs.microsoft.com/archive/blogs/gblock/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://review.docs.microsoft.com/archive/blogs/gblock/feed.xml</link>
    <description>Glenn Block - .NETFX




Another ALT.NET guy at Microsoft</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:23:20 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Updates to our Azure Cross Platform tools</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/updates-to-our-azure-cross-platform-tools</link>
      <pubDate>Fri, 09 Nov 2012 09:23:32 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2012/11/09/updates-to-our-azure-cross-platform-tools/</guid>
      <description><![CDATA[In my last post I talked about the new goodies we added to Powershell. Well I meant to get a follow...]]></description>
      <content:encoded><![CDATA[<p>In my last post I talked about the new goodies we added to Powershell. Well I meant to get a follow up post to tell you about many of the same features which we also added to cross plat “azure” command line tool, but fortunately <a href="http://blogs.msdn.com/b/silverlining">Larry</a> beat me to it! The list includes site settings, github deployment and my favorite much needed feature that I have been asking for for so long I was going to implement it myself!, site restart!, </p>  <p>Go check out his post here: <a title="http://blogs.msdn.com/b/silverlining/archive/2012/11/06/windows-azure-command-line-tools-for-mac-and-linux-version-0-6-7-is-available.aspx" href="http://blogs.msdn.com/b/silverlining/archive/2012/11/06/windows-azure-command-line-tools-for-mac-and-linux-version-0-6-7-is-available.aspx">http://blogs.msdn.com/b/silverlining/archive/2012/11/06/windows-azure-command-line-tools-for-mac-and-linux-version-0-6-7-is-available.aspx</a></p>  <p>Then repeat after me, “npm install azure –g”.</p>]]></content:encoded>
    </item>
    <item>
      <title>HuJS, bridging the international JavaScript divide</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/hujs-bridging-the-international-javascript-divide</link>
      <pubDate>Thu, 18 Oct 2012 22:22:39 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2012/10/18/hujs-bridging-the-international-javascript-divide/</guid>
      <description><![CDATA[Troy and I at HuJS   A few weeks ago we held an event in China called HuJS. This was an event...]]></description>
      <content:encoded><![CDATA[<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4452.clip_image002_7DFA17DC.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/4452.clip_5F00_image002_5F00_7DFA17DC.jpg"><img title="clip_image001[1]" style="border-width: 0px; display: inline;" border="0" alt="clip_image001[1]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4265.clip_image0011_04AD2160.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/4265.clip_5F00_image0011_5F00_04AD2160.jpg" width="514" height="571" /></a> </p>  <p><i>Troy and I at HuJS</i> </p>  <p>A few weeks ago we held an event in China called <a href="http://hujs.org">HuJS</a>. This was an event that <a href="https://twitter.com/thoward37">Troy Howard</a> and I dreamed up when I landed in China in July (Yes I was living in China for 3 months, but that is for another post!). With the the help of a great <a href="http://hujs.org/#contact">team</a> and with folks like <a href="https://twitter.com/mikeal">Mikeal Rogers</a> and <a href="https://twitter.com/voodootikigod">Chris Williams</a> advising us from the sidelines, we were able to make it happen.&#160; The event was a wonderful experience for me on multiple levels. We exchanged knowledge, we forged new bonds with the community, and we raised more international awareness about what JavaScript developers are doing in China. </p>  <p>For folks that travelled to China it was also an amazing cultural experience as they got to soak up the local sites and the local culture. We took the speakers to see some of the most amazing places in the world, like the Pearl Tower, and they got to mingle with the awesome folks at <a href="http://xinchejian.com/">Xinchejian</a>, the local hacker space. </p>  <p>&#160; </p>  <h3><u>Things that went wrong</u> </h3>  <p>Every conf has it’s high points and it’s low points. Our lowest point was definitely the internet access at the venue. They were not prepared for the number of connections and well it just went down on the second day. And lucky for me, it happened right before my talk while I was prepping. For cloud talks that’s pretty murderous. :-) </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/0068.clip_image00224_394D7D9B.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/0068.clip_5F00_image00224_5F00_394D7D9B.jpg"><img title="clip_image002[1]" style="border-width: 0px; display: inline;" border="0" alt="clip_image002[1]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/2627.clip_image0021_79176420.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/2627.clip_5F00_image0021_5F00_79176420.jpg" width="515" height="345" /></a> </p>  <p>&#160; </p>  <p>You can read the experiences of others who have attended in the posts below. </p>  <ul>   <li><a href="http://blog.lophilo.com/2012/09/report-from-nodejs-conference-in.html">http://blog.lophilo.com/2012/09/report-from-nodejs-conference-in.html</a> </li>    <li><a href="https://c9.io/site/blog/2012/09/the-javascript-community-in-china/">https://c9.io/site/blog/2012/09/the-javascript-community-in-china/</a> </li>    <li><a href="http://www.microsofttranslator.com/bv.aspx?from=&amp;to=en&amp;a=http://news.cnblogs.com/n/157911/">http://www.microsofttranslator.com/bv.aspx?from=&amp;to=en&amp;a=http://news.cnblogs.com/n/157911/</a> (translated) </li>    <li><a href="http://blog.nodejitsu.com/around-the-world-19-days">http://blog.nodejitsu.com/around-the-world-19-days</a> </li> </ul>  <p>&#160;</p>  <h2>The talks </h2>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/6835.clip_image00226_46B390A1.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/6835.clip_5F00_image00226_5F00_46B390A1.jpg"><img title="clip_image003[1]" style="border-width: 0px; display: inline;" border="0" alt="clip_image003[1]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/0243.clip_image0031_7B53ECDC.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/0243.clip_5F00_image0031_5F00_7B53ECDC.jpg" width="582" height="264" /></a> </p>  <p>The first part of the event was ran in a JSConf event style with a single track of back-to-back sessions covering two days. We were fortunate to have a really dynamic mix of <a href="http://hujs.org/#speakers">speakers</a> both local and abroad covering topics like node.js in the real world, async, webkit, JS frameworks and cloud. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/0045.clip_image00228_1B02C6A5.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/0045.clip_5F00_image00228_5F00_1B02C6A5.jpg"><img title="clip_image004" style="border-width: 0px; display: inline;" border="0" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/5758.clip_image004_36A7529B.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/5758.clip_5F00_image004_5F00_36A7529B.jpg" width="168" height="244" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/8156.clip_image00230_0F6D0966.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/8156.clip_5F00_image00230_5F00_0F6D0966.jpg"><img title="clip_image005[1]" style="border-width: 0px; display: inline;" border="0" alt="clip_image005[1]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4760.clip_image0051_7D2442A3.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/4760.clip_5F00_image0051_5F00_7D2442A3.jpg" width="172" height="244" /></a> </p>  <h2>Travel issues </h2>  <p>Two folks however were not able to make it, though they really tried, <a href="https://twitter.com/rauchg">Guillermo Roach</a> of socket.io fame and <a href="https://twitter.com/vmg">Vicent Marti</a> of github. Both tried to improvise and find a way to deliver a talk remotely. For Vicent we actually were able to pull this off (not without hitches) however unfortunately due to internet issues, Guillermo was not able to join us at all :-(. I was really excited to have him joining us so I was completely bummed that everything fell through. </p>  <p>Guillermo did however record a talk for us on building high performance applications using HTTP, WebSocket and SPDY. Watching it makes me wish even more that he had been present to deliver it as it has great technical content and real world experiences around scaling node! </p>  <p>You can go watch it right now <a href="http://cl.ly/0P2k1y1k1d1k">here</a>! </p>  <h2>Surprise speaker </h2>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/5430.clip_image007_6ADB7BE1.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/5430.clip_5F00_image007_5F00_6ADB7BE1.jpg"><img title="clip_image007" style="border-width: 0px; display: inline;" border="0" alt="clip_image007" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4452.clip_image007_thumb_63BC3F69.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/4452.clip_5F00_image007_5F00_thumb_5F00_63BC3F69.jpg" width="72" height="106" /></a> </p>  <p>In Guillermo’s place, we were fortunate to have <a href="https://twitter.com/domenic">Domenic Denicola</a> of Barnes and Noble step in at the last minute and give a great talk on client side JavaScript! </p>  <h2>My Rundown of sessions </h2>  <p>Unfortunately I did not get to attend all sessions (goes with the territory of running an event), but here are notes on the ones I did attend, which ironically was many more sessions than I usually attend for events I go to. </p>  <p><b>“Building international communities” by <a href="http://www.twitter.com/thoward37">Troy Howard</a></b>. </p>  <p>In this talk which kicked off the event Troy Howard from App Fog, tried to rally Chinese developers to join the global OSS community. He talked about the Apache project (which he is a member of) and encouraged local developers to use more FOSS and get involved and to committing to Apache projects as well as other OSS projects. He told them “I want to see your names on the commit logs.” It was an inspirational talk and the community really enjoyed it. </p>  <p><b>“0 TO 60 MOBILE WEB APPS WITH KNOCKOUT.JS AND AZURE MOBILE SERVICES” by <a href="https://twitter.com/stevensanderson">Steve Sanderson</a>.</b> </p>  <p><b></b>Steven gave an amazing talk. He built a taxi reservation app initially using Knockout.js and a server backend. He then migrated the application to the cloud using Azure Mobile Services. From the feedback people loved it. This particular quote was from one attendee. “It's quite possible that Microsoft may pull off a successful transition to open source, open web and cloud!” </p>  <p><b>“NODE.JS POT HOLES” by Yuan Feng. </b></p>  <p>Yuan Feng works at TaoBao, the EBay of China where they use node.js as part of their backend. His talk was lively and entertaining focusing on common but hidden pitfalls with node. Although his talk was in English, Yuan Feng went out of this way to provide English translation on each of his slides. The talk was interesting because Yuan Fang showed actual bugs they had encountered in their systems. </p>  <p><b>“INTERGALACTIC JAVASCRIPT ROBOTS FROM OUTER SPACE” by <a href="https://twitter.com/vmg">Vicent Marti</a>. </b></p>  <p>Vicent’s talk was on hubot, a bot authored in node.js which handles a lot of automated infrastructure tasks at Github. Hubot initially supported only IRC, but they added support for a ton of other protocols and it is extensible (Jabbr anyone). Hubot receives commands via chat which then cause it to kick off scripts which are written in coffeescript. The scripts will report back results which will get dumped to the channel. Some tasks are callable by anyone on the channel while others require authorization. Authorization is based on who the user actually is. The model is pretty simple and relies on in the IRC case that the user actually has a registered IRC name, thus they can be sure the person is who they say he is. I did ask myself a few times, why we don’t use this kind of automation internally ;-)The best part of Vicent’s talk were his slides which were amazingly professional and artistic in a comic book sort of way. </p>  <p>The major hitch of his talk was that he was unable to join us live. He did however reluctantly agree to try to deliver the session remotely. Internet in Shanghai is NOT good, so this was a pretty brave undertaking. Vicent recorded his video ahead of time and sent it to me. We then played the video during his talk with him watching the screen on skype and live video showing his face. To keep it interactive, periodically I would pause the video and ask him a question, or he would give some more clarity. We hit a few technical hitches due to bandwidth issues (as predicted), but the video quality was fantastic thanks to it being pre-recorded. After his talk he had a few minutes for live Q&amp;A with the audience which they really appreciated. </p>  <p><b>”PORTING NODE: THE JOURNEY FROM LAKE JAVASCRIPT TO THE STRAIT OF LUA” by <a href="https://twitter.com/creationix">Tim Caswell</a>. </b></p>  <p>I found this to be a fascinating. Tim kept a really good pace with this talk for non-english speakers. He described how he set out to write <a href="http://luvit.io/">Luvit</a>, a Lua port of node on top of libuv. The reason he did this is because Lua runs in a lot of embedded devices. One huge challenge for him was he did not know C++ or Lua when he started the project. Tim described in detail the process of learning Libuv and Lua and then mapping out node concepts to Lua, and adjustments he had to make based on language constraints. With the help of a community that formed around the project he managed to get pretty darn close. </p>  <p><b>“WIND. JS debugging and troubleshooting support” by <a href="http://github.com/JeffreyZhao">Jeffrey Zhao</a>. </b></p>  <p>Wind.js is a pretty interesting async framework. It is yet another example of folks dying to have async/await type syntax in JavaScript. Like Streamline, Wind.js does rewriting, however unlike Streamline it does this all at runtime and doesn’t require running anything other than node. The downside is the syntax is pretty verbose and it deeply pollutes your code. In this talk Jeffrey talked about Wind.js and how to debug. As he does all the rewriting at runtime he’s able to capture all the information in memory to map back to the original lines of code, something that Streamine does not do. I am not a fan of the Wind.js approach because of how it “infects” the code, but I do see how the runtime rewriting has significant benefits over static generation which Streamline uses. Aside from that&#160; it was great to see some really interesting node hacking happening in mainland China. </p>  <p><b>“Run with node.js for fun and profit” by <a href="https://twitter.com/indexzero">Charlie Robbins</a>. </b>This was a variant of an earlier talk I’ve seen Charlie give which basically talks about the evolution of node.js, and how it is exploding. He used the exponents of 10 approach starting at 10 to the power of 1 and working his way up at each level talking about how it relates to node starting with 10 to the 1<sup>st</sup> as the number of core committers and working his way up including plenty of nodejitsu&#160; along the way. One thing Charlie did that really resonated with the crowd is he pulled several Chinese words into his slides. It was a fun talk. Charlie has celebrity status here however so people loved the talk regardless of what he said :-) </p>  <p><b>“Apps these days are too big” by <a href="http://github.com/substack">James Halliday</a>. </b></p>  <p>The main them of James’s talk was about not building monolithic node applications. This has been a passion area for James as he has authored several diff modules to address the problem. The crux of his talk was encouraging folks to break as much code as possible into npm modules and to use modules like <a href="https://github.com/substack/fleet">fleet</a> and <a href="https://github.com/substack/seaport">seaport</a> to allow apps to easily scale and to distribute workloads across many machines and processes. Fleet is a git integrated mechanism for continuous deployment and for process management. Seaport is a centralized registry for network based services. James argued with Seaport you can have components in your system sitting side by side but using different versions of the same service. He said both modules have been hugely valuable to running the infrastructure for Browserling. </p>  <p><b>“The Secrets of Node revealed on Windows and Azure” by Glenn Block.</b> </p>  <p>My talk was focused on educating and eradicating misconceptions about Node.js as it relates to Microsoft, Windows and Azure. The talk was a bit campy as I used one of those secrets revealed documentaries type of theme. I started off first talking a bit about myself and how I ended up in Shanghai and putting on the event. Then I talked about node.js, how it initially did not work on Windows and how Microsoft jumped in to help node.js have a first class experience on Windows. Next I showed npm and how that works on Windows. Next I moved to the cloud talking about how node.js works in Azure and finally how you can deploy to it from any platform or even deploy Linux VMs. As part of the talk I did a bunch of demos of node, npm and finally Azure. The Azure demo hit some hitches due to some network issues. I worked around them by using the Azure portal to deploy. Overall I think the audience was shocked and surprised to see node working on Windows. After my talk I had a guy come up to me who runs a local startup and say “I used to hate Microsoft because they didn’t care about OSS, that changed when I saw you today”. That made me pretty happy J </p>  <p><b>“NEW APP('WINDOWS 8');” by Aiken Qi. </b></p>  <p>Aiken Qi gave a nice overview of Windows 8 application development and the JavaScript programming model. He demoed a Windows 8 app live and also walked through the code. I spoke to several folks after the talk and they were really excited to see the way Microsoft has embraced JavaScript for client development. </p>  <h2>Panels </h2>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/6318.clip_image0014_1F7BD81D.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/6318.clip_5F00_image0014_5F00_1F7BD81D.jpg"><img title="clip_image008" style="border-width: 0px; display: inline;" border="0" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/8407.clip_image008_31586BEA.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/8407.clip_5F00_image008_5F00_31586BEA.jpg" width="244" height="164" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/6406.clip_image0034_5826822A.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/6406.clip_5F00_image0034_5F00_5826822A.jpg"><img title="clip_image009" style="border-width: 0px; display: inline;" border="0" alt="clip_image009" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/8154.clip_image009_2CE1EB23.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/8154.clip_5F00_image009_5F00_2CE1EB23.jpg" width="244" height="165" /></a> </p>  <p>On both days we had a panel of the speakers for that day. That was really interesting because there was a mix of English an Mandarin speakers sitting side by side with questions coming from the audience for both and in two different languages J.&#160; The outcomes of the discussions were not so important, though there were some interesting ideas percolated. <u>The real I felt was in the international</u>. </p>  <p><b>Day 1</b> </p>  <p>On the first day the discussion was about frameworks. The first part was a frameworks vs libraries discussion for node of which most folks were on the side that you should prefer small libraries over frameworks. The second discussion was about javascript templating engines and which style of engines the speakers preferred, i.e. string based or DOM based. Most erred on the side of dom based, though Nodejitsu has an interesting model which plates which runs on the server and uses a string based representation of the DOM. Steve gave a really good explanation on the different between the different approaches which I really appreciated. Another topic that was covered was around the community in China and what folks in the panel thing China developers should do to be more involved. The basic sentiment was for folks to get more involved with OSS projects and to be active in the mailing lists. </p>  <p>I asked Charlie Robbins about native modules in node as it relates to cloud providers. Charlie said that nodejitsu fully supports native modules and that he believes all providers should do the same. His argument was there was just too many flavors of distros / configurations and that building was the only sure fire way to ensure it works. </p>  <p><b>Day 2</b> </p>  <p>The crux of the day 2 panel was about whether or not to use OOP libraries in JavaScript. The overall tone was don’t do it and embrace prototype, though a few folks thought it was perfectly fine to use OOP constructs. The second discussion was about coffeescript, should you use it or not. This came up in the context of Vicent’s talk on Hubot as it uses coffeescript. There was a split across the braod with the panelists. Some thought it was completely fine, others though it was horrible don’t do it and there were people in between. I spoke about my own personal pref which was to not use it in a published npm module though other than that it’s fine. One guy Domenic Denicola (from Barnes and Noble) pushed back and said if you are following James Halliday’s recommendation, then everything is a module thus you shouldn’t use Coffeescript at all. </p>  <p>Another question came up about which languages we use to develop. People cited various languages, but Domenic made an interesting comment, saying the only language here cares to learn nowadays is JavaScript and that with server support he needs nothing else. Domenic was a little biased as a lot of the work he is doing is mobile app based, where he is just using simple web apis on the backend and calling to other infrastructure. Several others agreed with him though that for many things, JS is sufficient today. </p>  <p>Finally the last question was directed to speakers asking them which cloud platform they prefer. A few of the foreign speakers said they use nodejitsu, though I definitely said Azure :-). I also said that I have used nodejitsu and it is nice for a very targetted node experience. I said that Azure offers the best hybrid cloud solution (PASS, IAAS, and On Prem support) and that I had heard that hybrid cloud was very important to several local folks I had spoken to. </p>  <h2>Hackathon </h2>  <p>Following the event we had a full day hackathon at <a href="http://www.people-squared.com/en/place/yanpingattic">PeopleSquared</a> where both speakers and attendees came together for some hardcore hacking. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/0647.clip_image001_7A11E4AE.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/0647.clip_5F00_image001_5F00_7A11E4AE.jpg"><img title="clip_image010" style="border-width: 0px; display: inline;" border="0" alt="clip_image010" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/0045.clip_image010_35D17D62.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/0045.clip_5F00_image010_5F00_35D17D62.jpg" width="269" height="397" /></a> </p>  <p><i>Bob Zheng of People Squared welcoming folks</i> </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/5758.clip_image003_2388B6A0.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/5758.clip_5F00_image003_5F00_2388B6A0.jpg"><img title="clip_image011" style="border-width: 0px; display: inline;" border="0" alt="clip_image011" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/5342.clip_image011_63529D25.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/5342.clip_5F00_image011_5F00_63529D25.jpg" width="558" height="376" /></a> </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4760.clip_image005_17F2F961.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/4760.clip_5F00_image005_5F00_17F2F961.jpg"><img title="clip_image012" style="border-width: 0px; display: inline;" border="0" alt="clip_image012" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/1220.clip_image012_42CB5D73.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/1220.clip_5F00_image012_5F00_42CB5D73.jpg" width="564" height="104" /></a> </p>  <p><i>Different teams at the hackathon</i> </p>  <p>We started off using an open space style with folks suggesting projects they wanted to work on. Then everyone voted or the sessions they liked and teams were split. </p>  <p>My team was with Tim Caswell where we were building a new tool called “crate” which will packages up a node application, it’s modules and node itself into a self-extracting / executing exe.. I helped with the design and actually picked the name, but unfortunately had to leave early due to a family commitment. The <a href="https://gitcafe.com/hujs">project</a> is up on <a href="http://www.gitcafe.com">gitcafe</a>, a new github like offering in China. </p>  <p>Several other really cool projects came out of the hackathon including a gravatar type service which has an avatar that changes dynamically based on your mood or time of the day. </p>  <p>The best part about the hackathon for me was the collaboration between local and international developers working together toward solving a problem. </p>  <h2>Summary</h2>  <p>HuJS was a fantastic experience. It was amazing to see developers from the opposite ends of the world with very different languages and customs come together, share and learn.</p>  <p>For the folks in China, I hope they came away feeling that although an ocean separates us, we have many things in common should work together. For folks that came from the US/Europe etc, remember when you are on the node / JavaScript lists that you have friends in China and think about their needs as developers. Do your best to bridge the gaps! </p>  <p>And as for the organizers, we hope this is the first of many China JS events to come. I am talking to you Beijing!</p>  <p>Thank you to our <a href="http://www.hujs.org/#sponsors">sponsors</a>, our organizers, our speakers and our attendees who made HuJS a possibility!</p>]]></content:encoded>
    </item>
    <item>
      <title>Integrating MVC routes and Web API routes</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/integrating-mvc-routes-and-web-api-routes</link>
      <pubDate>Thu, 04 Aug 2011 22:57:50 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/08/04/integrating-mvc-routes-and-web-api-routes/</guid>
      <description><![CDATA[&#160;  Several folks have been complaining for a while about Action Links not being properly...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>Several folks have been complaining for a while about Action Links not being properly generated when MVC routes are mixed with Service Routes in the same site.</p>  <p>It turns out there is a solution.....don't use ServiceRoute :-) Instead, create a derived route below and use it. [Kudos to <a href="http://www.haacked.com">Phil Haack</a> and <a href="http://blogs.msdn.com/b/clemensv/">Clemens Vasters</a> for this]</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> WebApiRoute : ServiceRoute
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     <span style="color: #0000ff">public</span> AppServiceRoute(<span style="color: #0000ff">string</span> routePrefix, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">       ServiceHostFactoryBase serviceHostFactory, Type serviceType)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     : <span style="color: #0000ff">base</span>(routePrefix, serviceHostFactory, serviceType)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">      
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> VirtualPathData GetVirtualPath(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">       RequestContext requestContext, RouteValueDictionary values)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">       <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>The link gen functionality uses the GetVirtualPath method to generate links. If you set it to null you are opting web api routes out of link gen and everything should work.</p>

<p>Now to register your routes using this model, don't use MapServiceRoute.</p>

<p>Instead, in add to your route table manually this way:</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var config = <span style="color: #0000ff">new</span> HttpHostConfiguration() <span style="color: #808080">///create your config object</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var factory = <span style="color: #0000ff">new</span> HttpConfigurableServiceHostFactory(config);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">routes.Add(<span style="color: #0000ff">new</span> WebApiRoute(&quot;<span style="color: #8b0000">Foo</span>&quot;, factory, <span style="color: #0000ff">typeof</span>(Foo)));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>It's a little bit more code, but not too much and hey, it fixes the problem. This will be fixed in the next drop, which YES, we are working on.</p>]]></content:encoded>
    </item>
    <item>
      <title>REST In Practice the book, RestBucks the sample</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/rest-in-practice-the-book-restbucks-the-sample</link>
      <pubDate>Mon, 06 Jun 2011 13:11:48 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/06/06/rest-in-practice-the-book-restbucks-the-sample/</guid>
      <description><![CDATA[The book  If you’ve watched any of my recent talks, one book you may have heard me mention quite a...]]></description>
      <content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/reader/0596805829/ref=sib_dp_pt#reader-link"><img border="0" alt="REST in Practice: Hypermedia and Systems Architecture" src="http://ecx.images-amazon.com/images/I/51xSVWRSEFL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" width="300" height="300" /></a></p>  <h1>The book</h1>  <p>If you’ve watched any of my recent talks, one book you may have heard me mention quite a bit is <a href="http://www.amazon.com/REST-Practice-Hypermedia-Systems-Architecture/dp/0596805829">“REST In Practice”</a> by <a href="https://twitter.com/#!/jimwebber">Jim Webber</a>, <a href="https://twitter.com/#!/savasp">Savas Parastatidas</a> and <a href="https://twitter.com/iansrobinson">Ian Robinson</a>. The thing I really like about this book that differentiates it from others on <a href="http://en.wikipedia.org/wiki/REST">REST</a> is that it broaches the concept of REST in the enterprise. This book is essential for those building RESTful business systems. It’s a book that has helped my own understanding tremendously and one that I find practically by my bedside. It covers topics that are of concern for folks taking business systems and moving them to a RESTFul architecture style. It also gradually takes people across the chasm from traditional RPC style services, to HTTP CRUD services and then finally to RESTful services.&#160; It is by no means the only book on the topic, as there are other good resources which I would also recommend like <a href="https://twitter.com/subbu">Subbu’s</a> work, <a href="http://oreilly.com/catalog/9780596801694">RESTful Web Services Cookbook</a>. </p>  <h1>RestBucks, the sample</h1>  <p>One of the cornerstones of the book is a reference application called <a href="http://savas.me/blog/932">RestBucks</a>, an application which takes the process of ordering coffee and exposes it electronically over HTTP using a set of RESTful services. The sample provides a great reference point for folks building RESTful systems to see how to address various concerns in a RESTful way. One key thing it addresses is the topic of hypermedia constraints / driving business processes through linking. Throughout the book we see various aspects of the sample implemented in various languages including Java and .NET. The .NET pieces utilize WCF 4. </p>  <h1>Now available for WCF Web API thanks to the community</h1>  <p>Since we announced WCF Web API, several folks have been asking for a port of RestBucks using our new web api. I actually started working on one, but due to other constraints never got around to making much progress. Fortunately folks from the community have stepped up to the plate! Several months back, Szymon Pobiega went and <a href="http://site.restbucks.net/">ported</a> the RestBucks code to use web api: <a title="https://github.com/SzymonPobiega/restbucks-wcf" href="https://github.com/SzymonPobiega/restbucks-wcf">https://github.com/SzymonPobiega/restbucks-wcf</a>. Checking the site, Szymon just recently updated the bits to Preview 4. </p>  <p>More recently, <a href="https://twitter.com/#!/jfroma">José Romaniello</a> of Tellago <a href="http://restbucks.codeplex.com/">released</a> another port of RestBucks which he blogged about. One nice thing about this port is it includes documentation pages for the various links as well as some good content via his growing blog series which you can access here: <a title="http://joseoncode.com/category/restbucks/" href="http://joseoncode.com/category/restbucks/">http://joseoncode.com/category/restbucks/</a>. Jose and I have chatted and he is committed to really fleshing out the docs and keep the sample alive. Another cool thing is that José has deployed RestBucks on App Harbour so you can access it live here! <a title="restbuckson.net" href="http://restbuckson.net/">restbuckson.net</a>. Remember these are RESTful apis, not web pages. You’ll want to use something like Fiddler to navigate the app. If you want to get the source, you can download it at the codeplex site here: <a title="http://restbucks.codeplex.com/" href="http://restbucks.codeplex.com/">http://restbucks.codeplex.com/</a>. BTW, he’s looking for commtters <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/3652.wlEmoticon-winkingsmile_2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/3652.wlEmoticon_2D00_winkingsmile_5F00_2.png" /></p>  <p>Big thanks to Szymon and José for the port!</p>  <p><strong>Get the book, get the samples!</strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Message Handlers vs Operation Handlers which one to use?</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/message-handlers-vs-operation-handlers-which-one-to-use</link>
      <pubDate>Tue, 17 May 2011 13:46:58 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/05/17/message-handlers-vs-operation-handlers-which-one-to-use/</guid>
      <description><![CDATA[In WCF Web API we have 2 extensibility points which seem very similar. They both are designed for...]]></description>
      <content:encoded><![CDATA[<p>In WCF Web API we have 2 extensibility points which seem very similar. They both are designed for very different reasons. Recently the question of which to use when <a href="http://wcf.codeplex.com/discussions/257984">popped</a> up on our forums. Below is some guidance.</p>  <h1>Message Handlers</h1>  <p>Message handlers (Currently DelegatingChannel but will be renamed to DelegatingHandler) only deal with http messages (hence the name), you can use them to modify the request or the response or to stop the request and immediately return a response. So in general you use message handlers for addressing http specific concerns, for example:</p>  <ul>   <li>Logging each request (logging the uri) </li>    <li>Checking for if-match / if-non-match headers and returning a 304 (not modified) </li>    <li>Embedding an ETag header in the response </li>    <li>Setting accept headers based on the uri (I do this in the ContactManager) </li>    <li>Checking for API keys as in Pablo's (@cibrax) Handler <a href="http://codepaste.net/b621hq">here</a>, or handling other security concerns like OAuth. (Our OAuth integration in the future will sit here.) </li> </ul>  <p>A few things to note about message handlers</p>  <ul>   <li>They are configured per host not per operation </li>    <li>They sit very low in the WCF stack in the channel layer making them ideal for security level concerns. </li>    <li>They are arranged in a russian doll model meaning each handler calls to it's inner handler. This lets you do plug in pre-post handling before the handler is called. </li>    <li>They only support async (Task&lt;T&gt;) </li> </ul>  <h1>Operation Handlers</h1>  <p>Opeation handlers (HttpOperationHandler)<strong>&#160;</strong>deal with taking the message and manufacturing the parameters for an operation or vice versa. It is the responsibility of the operation handler pipeline to ensure that for every parameter in the method there is a corresponding value it is also the responsibility of the pipeline to take any return/out values and modify the message appopriately with the correct representation. Those values can either be pulled from the message itself (such as parsing the uri into an object) or from custom logic like talking to a respository. The exception here is the value that represents the content of the message. It is the responsibility of the <strong>Formatters </strong>to handle taking the body and turning into an object or vice versa. Common use cases:</p>  <ul>   <li>Taking a portion of the URI and manufacturing an object. An example of this would be taking a uri like <a href="http://maps.com/location/100,00">http://maps.com/location/100,00</a> and turning it into a Location object with latitude / longitude properties. </li>    <li>Taking the content and compressing / decompressing it with gzip. Darrel Miller (@darrel_miller) has a nice example of this</li>    <li>Logging specific parameters of an operation </li>    <li>Validating the body, i.e. someone posts a customer in one of multiple formats. The formatter runs and turns it into a customer (based on conneg) and then the handler validates the model to see that the value are correct. </li> </ul>  <p>Here's the things to note about operation handlers.</p>  <ul>   <li>They are configured per operaiton not per host </li>    <li>Manufacture values which are used by other handlers in the pipeline or by the operation </li>    <li>They are arranged in a pipeline where each handler is called in succession but one handler does not call the other. </li>    <li>They only support sync in the box </li>    <li>They can stop the pipeline by throwing an HttpResponseException&lt;T&gt; </li> </ul>  <p>Which to use really depends on your scenarios. If you are trying to address pure http concerns use message handlers, if you are trying to address application level concerns that work with models etc, use operation handlers.</p>]]></content:encoded>
    </item>
    <item>
      <title>Using DataContracts with WCF Web API</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/using-datacontracts-with-wcf-web-api</link>
      <pubDate>Sat, 14 May 2011 19:45:37 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/05/14/using-datacontracts-with-wcf-web-api/</guid>
      <description><![CDATA[A few folks have been asking if it is possible to serialize/deserialize using the...]]></description>
      <content:encoded><![CDATA[<p>A few folks have been <a href="http://wcf.codeplex.com/discussions/248365">asking</a> if it is possible to serialize/deserialize using the DataContractSerializer. Rest assured, yes it is possible. Now whether or not it is the easiest/most intuitive model well that it is a different question. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/1440.wlEmoticon-winkingsmile_2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/1440.wlEmoticon_2D00_winkingsmile_5F00_2.png" /></p>  <p>If you read to the end the post you will see a bunch of extensions which have been pushed to webapicontrib and make this all MUCH easier (at least I think). If you don’t jump you’ll read below what you need to do if you do it yourself.</p>  <p>It stars with the SetSerializer&lt;T&gt; method which is expose on the XmlMediaTypeFormatter. You can call this method and pass a DataContractSerializer for T. That tells the formatter use this serializer not the default. You need to give it the exact information, for example if you are returning List&lt;Contact&gt; then make T List&lt;Contact&gt; NOT T. If you want to support both, you need to register both.</p>  <p>To allow you to get to the formatter, the MediaTypeFormatterCollection exposes an XmlFormatter property. You might now be thinking, “Oh that’s easy, but how do I get a hold of the formatter collection?”</p>  <p>Good question. It depends on whether you are on the server or on the client.</p>  <h1>On the Server</h1>  <p>The easiest way to configure things on the server is to annotate your service/resource with a [DataContractFormat] attribute. Once you do then we will automatically use the DataContractSerializer. </p>  <p>If you do not want to annotate your service, the alternative option is to do it in code. If you are using HttpHostConfiguration you can get to the formatters by accessing the OperationHandlerFactory property on the config class. If you are using the fluent API, you’ll want to cast to HttpHostConfiguration in order to access it. For example see the code below</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var config = <span style="color: #0000ff">new</span> HttpHostConfiguration();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var formatter = OperationHandlerFactory.XmlFormatter;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">formatter.SetSerializer&lt;Contact&gt;(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">new</span> DataContractSerializer(<span style="color: #0000ff">typeof</span>(Contact)));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">formatter.SetSerializer&lt;List&lt;Contact&gt;&gt;(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">new</span> DataContractSerializer(<span style="color: #0000ff">typeof</span>(List&lt;Contact&gt;)));</pre></pre>

<p>The code above is setting the formatter to use the DCS for Contact and List&lt;Contact&gt; both for reading and writing.</p>

<h1>On the client</h1>

<p>On the client side how you configure depends on if you are reading or writing. In either case both steps involve calling SetSerializer&lt;T&gt; on the XmlMediaTypeFormatter. </p>

<p>For reading you will create the formatter and pass it to the ReadAs&lt;T&gt; method of the HttpContent which is accessed off of the Content property on HttpResponseMessage.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var formatter = <span style="color: #0000ff">new</span> XmlMediaTypeFormatter();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">formatter.SetSerializer&lt;List&lt;Contact&gt;&gt;&gt;(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">new</span> DataContractSerializer(<span style="color: #0000ff">typeof</span>(List&lt;Contact&gt;))));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var contact = response.Content.ReadAs&lt;T&gt;(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">new</span> List&lt;MediaTypeFormatter&gt; { formatter });
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>If you are writing to the request, you will access the formatters collection on the ObjectContent&lt;T&gt; instance.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var content = <span style="color: #0000ff">new</span> ObjectContent&lt;Contact&gt;();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">content.Formatters.SetSerializer&lt;Contact&gt;(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">new</span> DataContractSerializer(<span style="color: #0000ff">typeof</span>(Contact)));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">client.Post(content);</pre></pre>

<h1></h1>

<h1>New extension methods in webapicontrib to make life easier</h1>

<p>Now that we’ve seen how you can do it, we can wrap this up in a bunch of helper extension methods and life gets a whole lot easier. I did that and <a href="http://webapicontrib.codeplex.com/SourceControl/changeset/view/2da8381982b9#source%2fFormatters%2fDataContractExtensions.cs">pushed</a> them to webapicontrib <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/1440.wlEmoticon-winkingsmile_2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-73-92-metablogapi/1440.wlEmoticon_2D00_winkingsmile_5F00_2.png" /></p>

<p>Check the code below from the new DataContractExample in webapicontrib.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var config = HttpHostConfiguration.Create();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><font style="background-color: #ffff00">config.UseDataContractSerializer&lt;Contact&gt;();</font>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var host = <span style="color: #0000ff">new</span> HttpConfigurableServiceHost&lt;ContactsResource&gt;(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  config, <span style="color: #0000ff">new</span> Uri(&quot;<span style="color: #8b0000">http://localhost:8080/</span>&quot;));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">host.Open();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var client = <span style="color: #0000ff">new</span> HttpClient(&quot;<span style="color: #8b0000">http://localhost:8080/</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var newContact = <span style="color: #0000ff">new</span> Contact {FirstName = &quot;<span style="color: #8b0000">Brad</span>&quot;, LastName = &quot;<span style="color: #8b0000">Abrams</span>&quot;};
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var content = <span style="color: #0000ff">new</span> ObjectContent&lt;Contact&gt;(newContact,
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  &quot;<span style="color: #8b0000">application/xml</span>&quot;).<font style="background-color: #ffff00">UseDataContractSerializer();</font>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var response = client.Post(&quot;<span style="color: #8b0000">contacts</span>&quot;, content);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">response = client.Get(&quot;<span style="color: #8b0000">contacts</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">var contacts = response.Content.<font style="background-color: #ffff00">ReadAsDataContract&lt;Contact[]&gt;();</font>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">foreach</span> (var contact <span style="color: #0000ff">in</span> contacts)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  Console.WriteLine(<span style="color: #0000ff">string</span>.Format(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    &quot;<span style="color: #8b0000">Contact: FirstName={0}, LastName={1}</span>&quot;, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    contact.FirstName, contact.LastName));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Console.ReadLine();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>I’ve highlighted the important parts</p>

<ol>
  <li>UseDataContractSerializer&lt;T&gt; on the config will set the formatter to serialize T using DCS. In order to make life easier the extension method also registers for List&lt;T&gt; and T[]. </li>

  <li>For reading on the client call the ReadAsDataContract&lt;T&gt; extension method on HttpContent. </li>

  <li>For writing on the client create an ObjectContent&lt;T&gt; instance and call the UseDataContractSerializer() extension metho </li>
</ol>

<p>Download the bits in wcfwebapi contrib <a href="http://webapicontrib.codeplex.com/SourceControl/list/changesets#">here</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Hypermedia and forms</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/hypermedia-and-forms</link>
      <pubDate>Sun, 08 May 2011 17:45:59 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/05/08/hypermedia-and-forms/</guid>
      <description><![CDATA[Updated (with a lot of new content)  One challenge when building REST based systems is how can the...]]></description>
      <content:encoded><![CDATA[<p><strong>Updated (with a lot of new content)</strong></p>  <p>One challenge when building REST based systems is how can the client determine what it can do next? There can be any number of clients each which need to interact with a system. How do they know HOW to interact? The WSDL approach is to offer a static snapshot of method calls on an API. That approach couples the client heavily to knowing everything about the server, including being coupled as to how things get processed. It inhibits evolvability. A change to the server usually results in breaking all clients. In a world where there are many 3rd party apps across devices consuming your server application this can be detrimental making it extremely difficult to move forward.</p>  <h1>Hypermedia</h1>  <p>Hypermedia (also referred to as Hypertext) is an answer. The word may sound scary but it basically means use links. When <a href="https://twitter.com/#!/timbernerslee">Tim Berners Lee</a>, <a href="https://twitter.com/#!/fielding">Roy Fielding</a>, and others (Al Gore :-) ) were envisioning the Web, linking was a key component of that design. We’re used to seeing links in UI contexts like a browser, i.e. using a web based ordering system you can click on an “Add Item” link to add the item. But what about in a non-UI context? Well guess what, you can use links there as well. </p>  <p>With a hypermedia approach your server doesn’t only return data. It returns data + links. Those links provide a means for the client to discover the available sets of options that make sense based on where the client is at in the application. A link has 2 standard components, a <em>url</em> for the link and a <em>rel</em>. REL in this case stands for relation and describes to the client how the link relates to the current resource. For example, let’s take a catalog / shopping cart experience exposed in a RESTful way. When browsing the catalog, you get back a&#160; list of items. Each item can have links for adding the item to a cart. Below is one such item.</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">item</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">productNo</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">itemNo</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">description</span><span style="color: #0000ff">&gt;</span>An item<span style="color: #0000ff">&lt;/</span><span style="color: #800000">description</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">price</span><span style="color: #0000ff">&gt;</span>$19.95<span style="color: #0000ff">&lt;/</span><span style="color: #800000">price</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">sku</span><span style="color: #0000ff">&gt;</span>123456789<span style="color: #0000ff">&lt;/</span><span style="color: #800000">sku</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">link</span> <span style="color: #ff0000">rel</span>=<span style="color: #0000ff">&quot;rc:additem&quot;</span> <span style="color: #ff0000">url</span>=<span style="color: #0000ff">&quot;/cart/12456/items&quot;</span><span style="color: #0000ff">/&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">item</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>Above the server returned a&#160; link for adding an item. Unlike an operation in a WSDL, that link it not static, and hardcoded as part of the contract. The server is offering the links that make sense at specific point in time based on the application and resource state. Assuming for example that “An Item” is out of stock, the client will not get a link for adding and item. Instead it may get a link to place the item on backorder. The client however doesn’t have any knowledge of the rules on the server. It doesn’t know that because the item is out of stock, it can’t add it. All it knows is that rel=”rc:additem” is not present. The server logic might be more sophisticated, maybe there are limits set on how much I can order of a specific item. From the client perspective though all it knows is the link is not present. That’s decoupling.</p>

<p>What about evolvability? The beauty of linking is that clients only care about the links they know, they don’t care about the links they don’t. That means as the server evolves it can offer additional links. For example we may decide to offer clients the ability to put an item in a wish-list rather than in the shopping cart. That means an additional link is returned such as the following:</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">link</span> <span style="color: #ff0000">rel</span>=<span style="color: #0000ff">&quot;rc:addtowishlist&quot;</span> <span style="color: #ff0000">url</span>=<span style="color: #0000ff">&quot;/wishlist/gblock&quot;</span><span style="color: #0000ff">/&gt;</span></pre></pre>

<p>&#160;</p>

<p>Older clients won’t know about the wish list. They will however continue to function. Newer clients will&#160; easily consume the new functionality. If you imagine a world with many different clients consuming (which is real), that is huge! There’s&#160; a further benefit for the older clients. The server has advertised the fact that there are new capabilities. Clients can be designed to track links they don’t know such that they can log that there are new capabilities available.</p>

<p>An additional benefit of the link approach has to do with the urls themselves. Clients are agnostic to&#160; to building urls, thus the server can completely change the format of the url, or even where the urls point to without the client being impacted _at_all. </p>

<p><a href="https://twitter.com/#!/jon_moore">Jon Moore</a>, a Technical Fellow at Comcast has a great talk / demonstration on how this works which he delivered at <a href="http://oredev.org/2010/sessions/hypermedia-apis">Oredev</a>. I highly recommend it.</p>

<h1>What to with a link and why forms are interesting?</h1>

<p>So now we have links. But there’s one problem, how does the client know what to do them?&#160; Which HTTP method should be used, is it an HTTP GET, POST, etc? If it is a POST what type of content should be sent and in what form? Another challenge is around versioning, once a service has been updated, how do the clients know know how to upgrade that client to take advantage of the new functionality.</p>

<p>One solution is simple, read the spec. When you build hypermedia based systems you aren’t simply returning a media type (Content-Type header value)&#160; of “application/xml” or “application/json”. Rather you are returning something more specific such as “application/atom+xml” or something even more domain specific such as in tje new “<a href="http://oreilly.com/catalog/9780596805838">REST in Practice book</a>” where the system uses the media type of “application/vnd-restbucks+xml”. Each media type has an RFC/spec associated with it. Thus if a client author reads the spec, it should document what to expect from a links perspective and which method / media type to use.</p>

<p>That is one approach and it <strong>absolutely</strong> works. The downside of that approach is the client has to be encoded with specific knowledge of how to work with each link. </p>

<p>That is not the only approach however and one really interesting one is Forms.</p>

<h1>Forms</h1>

<p>If we look to HTML we can see some hints on how to address these issues. In a web page, if you click a link such as “Add Item”, the common paradigm is for the server to return an HTML form (the client may also display one through some client script). That form provides information to the human who is reading the site to help them move forward. The Form contains an action that points to uri, and method, as well as other fields which may be either prefilled by the server, or require input from the user. The model works basically in a seem-less fashion. The site can freely evolve as it can offer different forms to different users based on a number of factors including what “version” of the app they are using, their user profile etc.</p>

<p>Now imagine there is no human. There’s a machine client that is consuming some resources over HTTP. That machine may be jQuery code running in a browser, maybe be code executing in a rich client app such as WPF, Silverlight, Flash, or even a Java applet. Or it may be headless server code that is accessing that information. Ultimately the information will be likely surfaced to some human, but that is after some initial processing has taken place. For example there might be an agent that automatically processors orders using a 3rd party fulfillment service.</p>

<p>We can design electronic forms which our servers offer to clients to guide them on how to use the link to transition to the next state.</p>

<p>With this approach, each link is a GET that returns an electronic form. That form specifies url, method as well as pre-filled information from the server such as Item details. The form may also specify required fields such as a Quantity field.</p>

<p>The advantage of forms is they allow the client to be less coupled to knowledge of how to work with links, which yields greater evolvability. </p>

<p>For example for adding item '1'&#160; to a shopping cart, the server may return the client a link such as the following.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">link</span> <span style="color: #ff0000">rel</span>=<span style="color: #0000ff">&quot;rc:AddItem&quot;</span> <span style="color: #ff0000">url</span>=<span style="color: #0000ff">&quot;/restcart/forms/additem/1&quot;</span> <span style="color: #0000ff">/&gt;</span></pre>
<p></p></pre>

<p></p>

<p>&#160;</p>

<p>The client then automatically does a GET on the link and retrieves an AddItem form that looks like the following.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">form</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">url</span><span style="color: #0000ff">&gt;</span>/restcart/cart/12456<span style="color: #0000ff">&lt;/</span><span style="color: #800000">url</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">method</span><span style="color: #0000ff">&gt;</span>POST<span style="color: #0000ff">&lt;/</span><span style="color: #800000">method</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">mediatype</span><span style="color: #0000ff">&gt;</span>vnd-restcart+xml<span style="color: #0000ff">&lt;/</span><span style="color: #800000">mediatype</span><span style="color: #0000ff">&gt;</span> 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">item</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">productNo</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">itemNo</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">description</span><span style="color: #0000ff">&gt;</span>An item<span style="color: #0000ff">&lt;/</span><span style="color: #800000">description</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">price</span><span style="color: #0000ff">&gt;</span>$19.95<span style="color: #0000ff">&lt;/</span><span style="color: #800000">price</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">sku</span><span style="color: #0000ff">&gt;</span>123456789<span style="color: #0000ff">&lt;/</span><span style="color: #800000">sku</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">item</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">required</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">quantity</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">quantity</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">required</span><span style="color: #0000ff">&gt;</span> 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">form</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>This form offers the client everything it needs to move forward. It does not have to build up the item information to POST as it has already been sent by the server. The server also specifies the media type for the client to use. This form additionally specifies that the client must provide a quantity.</p>

<p>To move forward, the client will POST to the specified url using the included item as the body. As required fields are specified, the client must supply those as well.</p>

<p>The server can also embed a token in the response in order to ensure the price of the item is valid for a period of time (say 2 hours). If there is no such guarantee or the time has expired, the server can return a status code of 409 (Conflict) to the client indicating that it needs to refresh the form.</p>

<p>*Note: There are alternative approaches to exposing the cart as a resource, for example the CART state could be maintained on the client and sent with the POST. In either case it would not rely on session state.</p>

<h1>Summary</h1>

<p>Hypermedia allows clients and servers to independently evolve. In this approach the server offers clients well known links at every stage of the client/server interaction in order to to guide the client as to what they can do next.</p>

<p>There are various approaches to implementing a hypermedia based system, including using electronic forms.</p>

<p>You mileage may vary as to whether you need this or not.</p>

<p>Interested in your thoughts.</p>

<h3>Links</h3>

<ul>
  <li>Roy’s chapter on REST in his dissertation: <a title="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm</a> </li>

  <li>Roy’s post on REST APIs and the need for hypertext - <a title="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven" href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven</a> </li>

  <li>Jon Moore on “Hypermedia APIs” - <a title="Hypermedia APIs" href="http://oredev.org/2010/sessions/hypermedia-apis">Hypermedia APIs</a> </li>

  <li>REST and Domain application protocols - <a href="http://iansrobinson.com/2010/10/15/restful-domain-application-protocols/">http://iansrobinson.com/2010/10/15/restful-domain-application-protocols/</a> </li>

  <li>Links and forms - <a href="http://iansrobinson.com/2010/09/02/using-typed-links-to-forms/">http://iansrobinson.com/2010/09/02/using-typed-links-to-forms/</a> </li>

  <li>My hypermedia talk at Dev Days 2011 - <a href="https://channel9.msdn.com/Events/DevDays/DevDays-2011-Netherlands/Devdays017">https://channel9.msdn.com/Events/DevDays/DevDays-2011-Netherlands/Devdays017</a> </li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>WebSockets, RIA/JS and WCF Web API at MIX, a whole lotta love for the web</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/websockets-riajs-and-wcf-web-api-at-mix-a-whole-lotta-love-for-the-web</link>
      <pubDate>Sun, 24 Apr 2011 02:52:23 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/04/24/websockets-riajs-and-wcf-web-api-at-mix-a-whole-lotta-love-for-the-web/</guid>
      <description><![CDATA[MIX was indeed a busy time for the WCF Team. We delivered several talks, and released several...]]></description>
      <content:encoded><![CDATA[<p><img src="http://farm3.static.flickr.com/2634/3867034897_32f913f353_z.jpg" /></p>  <p>MIX was <em>indeed</em> a busy time for the WCF Team. We delivered several talks, and released several shiny new toys to the community for folks that are building web-based systems.</p>  <h1>WebSockets</h1>  <p><a href="https://twitter.com/#!/craigkitterman">Craig Kitterman</a> of our Interoperability group, and <a href="https://twitter.com/#!/paulbatum">Paul Batum</a>, whom you might <a href="http://www.paulbatum.com/">know of</a> from his work on Fluent NHibernate gave a talk: <a href="https://channel9.msdn.com/events/mix/mix11/HTM10">Hot from the Labs: HTML5 WebSockets</a></p>  <div><object type="application/x-silverlight-2" data="data:application/x-silverlight-2," width="512" height="288"><param name="minRuntimeVersion" value="4.0.50401.0" /><param name="source" value="https://channel9.msdn.com/scripts/Channel9.xap?v=1.5" /><param name="initParams" value="mediaurl=http://smooth.ch9.ms/ch9/DF00/3E505E08-3564-45A3-866D-9EB60082DF00/MIX11HTM10.ism/manifest,thumbnail=http://files.ch9.ms/mix/2011/thumbs/HTM10_lg.jpg,deliverymethod=adaptivestreaming,autoplay=false,entryid=3e505e08356445a3866d9eb60082df00" /></object></div>  <p>In the talk they spoke about new explorations we are doing into supporting WebSockets in the Microsoft Stack. WebSockets is basically sockets for the web, i.e. a way to have a much more responsive in-browser experience. In the talk you’ll learn about the work going on in the W3C/IETF around WebSockets and you’ll see the exploratory work we’ve been doing both at the browser level and on the server to enable a WebSockets experience. I highly recommend this talk, as you’ll see is a pattern for the other talks I mention below.</p>  <p>Here’s a sneak peak of what the coding experience looks like, which I hope you agree is pretty clean.</p>  <p>On the client you have code such as the following:</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">conn.onopen = <span style="color: #0000ff">function</span> () {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  state.className = 'success';
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  state.innerHTML = 'Socket <span style="color: #0000ff">open</span>';
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">};
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">conn.onmessage = <span style="color: #0000ff">function</span> (event) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">var</span> message = JSON.parse(event.data);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">if</span> (<span style="color: #0000ff">typeof</span> message == 'string') {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    log.innerHTML = '&lt;li <span style="color: #0000ff">class</span>=&quot;<span style="color: #8b0000">them</span>&quot;&gt;' + 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    message.replace(/[&lt;&gt;&amp;]/g, <span style="color: #0000ff">function</span> (m) 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    { <span style="color: #0000ff">return</span> entities[m]; }) + '&lt;/li&gt;' + log.innerHTML; 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  } <span style="color: #0000ff">else</span> {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    connected.innerHTML = message;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">};
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">conn.onclose = <span style="color: #0000ff">function</span> (event) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  state.className = 'fail';
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  state.innerHTML = 'Socket <span style="color: #0000ff">closed</span>';
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">};</pre></pre>

<p>The on the server you have a WebSocket service:</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  ConcurrencyMode = ConcurrencyMode.Multiple)]
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ChatService : WebSocketsService
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  ...
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnMessage(<span style="color: #0000ff">string</span> <span style="color: #0000ff">value</span>)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    ChatService.sessions.RelayMessage(<span style="color: #0000ff">this</span>, <span style="color: #0000ff">value</span>);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">int</span> GetHashCode()
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.id; 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnClose(<span style="color: #0000ff">object</span> sender, EventArgs e)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    ChatService.sessions.Remove(<span style="color: #0000ff">this</span>);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<h1><font color="#333333" size="3" face="Segoe UI">You can download the latest bits of the WebSockets work at <a href="http://html5labs.interoperabilitybridges.com/html5labs/prototypes/websockets/websockets/info/">the HTML 5 labs WebSockets page</a>.</font></h1>

<h1>RIA/JS</h1>

<p><a href="https://twitter.com/#!/brado_23">Brad Olenick</a> of the RIA team delivered a talk: <a title="Building Data-centric N-tier Applications with jQuery" href="https://channel9.msdn.com/events/MIX/MIX11/FRM05">Building Data-centric N-tier Applications with jQuery</a>. </p>

<div><object type="application/x-silverlight-2" data="data:application/x-silverlight-2," width="512" height="288"><param name="minRuntimeVersion" value="4.0.50401.0" /><param name="source" value="https://channel9.msdn.com/scripts/Channel9.xap?v=1.5" /><param name="initParams" value="mediaurl=http://files.ch9.ms/mix/2011/wmv/FRM05.wmv,thumbnail=http://files.ch9.ms/mix/2011/thumbs/FRM05_lg.jpg,deliverymethod=progressivedownload,autoplay=false,entryid=c41ecd9aa986486c99469eaf0092f8ee" /></object></div>

<p>In the talk he unveiled new work the RIA team is doing is to allow consuming RIA services in jQuery! Watch the talk. Brad demonstrates how you can build a rich jQuery front end that dynamically pulls down all of it’s data to the client using RIA. RIA/JS then integrates all the state-tracking/validation richness and such using jQuery validators.&#160; If you are building data-centric jQuery based applications then RIA can take care of a lot of the dirty work for you making your job easier*. This also highlights the value of RIA in that I can reuse my existing domain services now both across Silverlight and Javascript! I know my previous boss (who is deeply missed)&#160; <a href="http://bradabrams.com/2010/05/going-google/">Brad Abrams</a> must be very happy seeing that this is being developed! </p>

<p>*We’re not saying RIA/JS is the panacea for all evils, but it certainly is for some :-)</p>

<p>Here are some of the key scenarios being supported in the first preview.</p>

<ol>
  <li>Query support with sorting, paging, filtering </li>

  <li>Changeset submission with two edit modes: 
    <ol>
      <li>“Implicit Commit” or “write-thru edits” where updates to field values are automatically submitted to your DomainService. This can enable a Netflix.com or Mint.com experience where field changes are submitted to the server as soon as the user tabs out of the field. </li>

      <li>“Buffered Changes” mode, where your code must call commitChanges() to submit your changeset to the DomainService. Those that have used the Silverlight client will be most familiar with this mode - a submit button is often used to trigger the commit. </li>
    </ol>
  </li>

  <li>Data change events including collection changes </li>

  <li>Client-side change tracking with an entity state API for determining what entities and properties have been edited </li>

  <li>Entity data model support that allows you to navigate through associated entity properties and collections </li>

  <li>Client-side validation by exposing your server-side validation metadata in jQuery validation format </li>
</ol>

<p>And here is a snippet of the new RIA/JS syntax. This is a great example of how we are looking to take advantage of awesome OSS solutions for delivering value. It’s about time!</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">&lt;script type=&quot;<span style="color: #8b0000">text/javascript</span>&quot;&gt;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  $(<span style="color: #0000ff">function</span> () {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	<span style="color: #0000ff">var</span> serviceUrl = &quot;<span style="color: #8b0000">/CustomerApp-CustomerService.svc</span>&quot;;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	<span style="color: #0000ff">var</span> customers = [];
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	<span style="color: #0000ff">var</span> render = <span style="color: #0000ff">function</span> (loadedCustomers) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	  $(&quot;<span style="color: #8b0000">#customerForm input[name='CustomerName']</span>&quot;).
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	    val(loadedCustomers[0].CustomerName);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	  $(&quot;<span style="color: #8b0000">#customerForm</span>&quot;).link(loadedCustomers[0]);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	};
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	$([customers]).dataSource({
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	  serviceUrl: serviceUrl,
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	  queryName: &quot;<span style="color: #8b0000">GetCustomers</span>&quot;,
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	  refresh: render
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">	}).refresh();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  });
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">&lt;/script&gt;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">&lt;div id=&quot;<span style="color: #8b0000">customerForm</span>&quot;&gt;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    Name: &lt;input type=&quot;<span style="color: #8b0000">text</span>&quot; <span style="color: #0000ff">name</span>=&quot;<span style="color: #8b0000">CustomerName</span>&quot; /&gt;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">&lt;/div&gt;</pre></pre>

<p>After the talk, the RIA team shipped new bits (as in js files) to Codeplex and a new <a href="http://nuget.org/list/packages/RIAServices.jQuery">RIA Service jQuery Nuget</a> package! allowing you to start to play with the RIA/JS stuff now.&#160; Go get-em <a href="http://bit.ly/wcfjquery">here</a>.</p>

<h1>WCF Web API and Preview 4</h1>

<p>Continuing along the path web goodness, I delivered a talk: <a href="https://channel9.msdn.com/Events/MIX/MIX11/FRM14">WCF Web APIs: There’s a URI for that</a>. </p>

<div><object type="application/x-silverlight-2" data="data:application/x-silverlight-2," width="512" height="288"><param name="minRuntimeVersion" value="4.0.50401.0" /><param name="source" value="https://channel9.msdn.com/scripts/Channel9.xap?v=1.5" /><param name="initParams" value="mediaurl=http://files.ch9.ms/mix/2011/wmv-hq/FRM14-HD.wmv,thumbnail=http://files.ch9.ms/mix/2011/thumbs/FRM14_lg.jpg,deliverymethod=progressivedownload,autoplay=false,entryid=2aeb0e9aabff4e7da5be9eaf0092fab8" /></object></div>

<p>In the talk I covered the evolution of systems that are now making their capabilities directly available over HTTP including social sites and line of business / enterprise apps. I showed progress we’ve made since PDC on our new WCF addition. The advances have been significant including greatly improving the out of the box experience, enhancing the fidelity you can have when working with HTTP,&#160; improving the configuration story and improving testability. </p>

<p>For example I demonstrated how using our new nuget package, you&#160; quickly you can build a simple service that can return and consume xml, json as well as consume form url encoding content. I then throw an existing jQuery front end on top without having to touch the server side configuration. I then demonstrated how I could easily take my existing service and quickly refactor it to use an IoC container, in this case Autofac, by taking advantage of a new fluent api (which is still a work in progress).</p>

<p>In the second part of my talk, I demonstrated how having rich control of formats/media types can benefit you. This includes showing my resource returning OData, as well a vcard implementation which I use to import contacts directly into gmail. Try that with SOAP, or plain-old XML/JSON, I dare you!</p>

<p>Here’s a snippet of some of the HTTP fidelity I am talking about. Below my service takes advantage of our new HttpResponseMessage&lt;T&gt; and HttpResponseException to return a model AND work with HTTP at the same time. </p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">[WebGet(UriTemplate = &quot;<span style="color: #8b0000">{id}</span>&quot;)]
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> HttpResponseMessage&lt;Contact&gt; Get(<span style="color: #0000ff">int</span> id)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  var contact = <span style="color: #0000ff">this</span>.repository.Get(id);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">if</span> (contact == <span style="color: #0000ff">null</span>)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    var response = <span style="color: #0000ff">new</span> HttpResponseMessage();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    response.StatusCode = HttpStatusCode.NotFound;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    response.Content = <span style="color: #0000ff">new</span> StringContent(&quot;<span style="color: #8b0000">Contact not found</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> HttpResponseException(response);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   var contactResponse = 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     <span style="color: #0000ff">new</span> HttpResponseMessage&lt;Contact&gt;(contact);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   <span style="color: #008000">//set it to expire in 5 minutes</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   contactResponse.Content.Headers.Expires = 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">     <span style="color: #0000ff">new</span> DateTimeOffset(DateTime.Now.AddSeconds(30));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   <span style="color: #0000ff">return</span> contactResponse;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>The Get method returns a contact and sets caching headers. If the contact is not found however it throws an HttpResponseException passing in an HttpResponseMessage. In this case I am just returning a string, but you have full access to set the response headers/content to whatever you want. Also you might not have caught it, but the id parameter is now passed in as integer. In previous drops as well as in WCF HTTP you had to use a string. Well now we do automatic type conversion. You asked for it, and you got it!</p>

<h1>Nuget and Preview 4</h1>

<p>After my talk, I am happy to announce that we pushed our next release of WCF Web API (yes drop the s) to <a href="http://wcf.codeplex.com/releases/view/64449">Codeplex</a> along with a new set of <a href="http://nuget.org/List/Search?packageType=Packages&amp;searchCategory=All+Categories&amp;searchTerm=webapi+httpclient+jsonvalue&amp;sortOrder=package-download-count&amp;pageSize=10">Nuget packages</a> (webapi.all will get all of ours). You’ll notice a 6th package, <a href="http://nuget.org/List/Packages/WebApi.CrudHttpSample">WebApi.CrudHttpSample</a> from <a href="http://geekswithblogs.net/michelotti/Default.aspx">Steve Michelotti</a>. Rock on Steve! Here’s a <a href="http://geekswithblogs.net/michelotti/archive/2011/04/21/wcf-web-api-is-pure-simplicity-with-nuget.aspx">link</a> to more on that package.</p>

<p>Preview 4 is <em><u>loaded </u></em>with new features much of which is based on your feedback! We’ve been developing them for a while and finally are able to get them out there. All of our apis have been significantly evolved in this release.</p>

<p>Here is a summary of the major things you will find:</p>

<ul>
  <li>
    <p>New message classes HttpResponseMessage&lt;T&gt; / HttpRequestMessage&lt;T&gt; allows accessing headers and using a strongly typed model.</p>
  </li>

  <li>
    <p>Uri parameters can now autocast to primtiive types, i.e. a uri template of &quot;{id}&quot; can map to an integer parameter of id.</p>
  </li>

  <li>
    <p>Matching of parameters is now by type if there is no match on name, ie. HttpRequestMessage req will work.</p>
  </li>

  <li>
    <p>New Operation Handlers which replace processors and dramatically improve the authoring</p>
  </li>

  <li>
    <p>New Formatters for plugging in custom media types</p>
  </li>

  <li>
    <p>New Message Handlers for low level control over HTTP</p>
  </li>

  <li>
    <p>Newer HttpClient</p>
  </li>

  <li>
    <p>Support for Form Url Encoding / Json and Xml out of the box.</p>
  </li>

  <li>
    <p>Support for HTTPs</p>
  </li>

  <li>
    <p>IQueryable support with IQueryable&lt;T&gt; and without requiring attributes</p>
  </li>

  <li>
    <p>Overhauled<strong> fluent API for configuration !!!!</strong></p>
  </li>

  <li>
    <p>Unit tests</p>
  </li>

  <li>
    <p>New samples</p>
  </li>

  <li>
    <p>ContactManager is now a fully client based AJAX / JQuery application</p>
  </li>

  </ul><ul>
    <li>
      <p>New ContactManager_Simple illustrates the bare basics.</p>
    </li>
  </ul>

  <ul><li>
    <p>new HelloResource sample</p>
  </li>

  <li>
    <p><strong>Acceptance and Unit tests for some of the samples </strong></p>
  </li>
</ul>

<p>I am planning to do some follow up posting detailing all these changes, but this should be enough to keep you guys happy for a while <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/8304.wlEmoticon-smile_2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/8304.wlEmoticon_2D00_smile_5F00_2.png" /></p>

<p>Go road test this stuff and give us your feedback. <strong>We want it</strong>, we’re not done yet! </p>]]></content:encoded>
    </item>
    <item>
      <title>Adding vcard support and bookmarked URIs for specific representations with WCF Web Apis</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/adding-vcard-support-and-bookmarked-uris-for-specific-representations-with-wcf-web-apis</link>
      <pubDate>Mon, 07 Mar 2011 06:51:11 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/03/07/adding-vcard-support-and-bookmarked-uris-for-specific-representations-with-wcf-web-apis/</guid>
      <description><![CDATA[REST is primarily about 2 things, Resources and Representations. If you’ve seen any of my recent...]]></description>
      <content:encoded><![CDATA[<p>REST is primarily about 2 things, Resources and Representations. If you’ve seen any of my recent talks you’ve probably seen me open Fiddler and how our ContactManager sample supports multiple representations including Form Url Encoded, Xml, Json and yes an Image. I use the image example continually not necessarily because it is exactly what you would do in the real world, but instead to drive home the point that a representation can be anything. Http Resources / services can return anything and are not limited to xml, json or even html though those are the most common media type formats many people are used to.</p>  <p>One advantage of this is your applications can return domain specific representations that domain specific clients (not browsers) can understand. What do I mean? Let’s take the ContactManager as an example. The domain here is contact management. Now there are applications like Outlook, ACT, etc that actually manage contacts. Wouldn’t it be nice if I could point my desktop contact manager application at my contact resources and actually integrate the two allowing me to import in contacts? Turns out this is where media types come to the rescue. There actually is a format called <a href="http://en.wikipedia.org/wiki/VCard">vcard</a> that encapsulates the semantics for specifying an electronic business card which includes contact information. <a href="http://tools.ietf.org/html/rfc2425">rfc2425</a> then defines a “text/directory” media type which clients can use to transfer vcards over HTTP.</p>  <p>A sample of how a vcard looks is below (taken form the rfc)</p>  <p><strong>begin:VCARD      <br />source:ldap://cn=bjorn%20Jensen, o=university%20of%20Michigan, c=US       <br />name:Bjorn Jensen       <br />fn:Bj=F8rn Jensen       <br />n:Jensen;Bj=F8rn       <br />email;type=internet:bjorn@umich.edu       <br />tel;type=work,voice,msg:+1 313 747-4454       <br />key;type=x509;encoding=B:dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK       <br />end:VCARD</strong></p>  <p>Notice, it is not xml, not json and not an image :-) It is an arbitrary format thus driving the point I was making about the flexibility of HTTP. </p>  <h1>Creating a vcard processor</h1>  <p>So putting two and two together that means if we create a vcard processor for our ContactManager that supports “text/directory” then Outlook can import contacts from the ContactManager right? </p>  <p>OK, here is the processor for VCARD.</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> VCardProcessor : MediaTypeProcessor
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> VCardProcessor(HttpOperationDescription operation)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        :<span style="color: #0000ff">base</span>(operation, MediaTypeProcessorMode.Response)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> IEnumerable&lt;<span style="color: #0000ff">string</span>&gt; SupportedMediaTypes
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">get</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            yield <span style="color: #0000ff">return</span> &quot;<span style="color: #8b0000">text/directory</span>&quot;;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> WriteToStream(<span style="color: #0000ff">object</span> instance, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">      Strea stream, HttpRequestMessage request)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        var contact = instance <span style="color: #0000ff">as</span> Contact;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">if</span> (contact != <span style="color: #0000ff">null</span>)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var writer = <span style="color: #0000ff">new</span> StreamWriter(stream);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            writer.WriteLine(&quot;<span style="color: #8b0000">BEGIN:VCARD</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            writer.WriteLine(<span style="color: #0000ff">string</span>.Format(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                &quot;<span style="color: #8b0000">FN:{0}</span>&quot;, contact.Name));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            writer.WriteLine(<span style="color: #0000ff">string</span>.Format(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                 &quot;<span style="color: #8b0000">ADR;TYPE=HOME;{0};{1};{2}</span>&quot;, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                 contact.Address, contact.City, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                 contact.Zip));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            writer.WriteLine(<span style="color: #0000ff">string</span>.Format(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                 &quot;<span style="color: #8b0000">EMAIL;TYPE=PREF,INTERNET:{0}</span>&quot;, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                 contact.Email));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            writer.WriteLine(&quot;<span style="color: #8b0000">END:VCARD</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            writer.Flush();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">object</span> ReadFromStream(Stream stream, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        HttpRequestMessage request)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> NotImplementedException();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>The processor above does not supporting posting vcard, but it actually could.</p>

<p>Right. However there is one caveat, Outlook won’t send Accept headers <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/0045.wlEmoticon-winkingsmile_1729B2BE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/0045.wlEmoticon_2D00_winkingsmile_5F00_1729B2BE.png" />, all it has a “File-Open” dialog.&#160; There is hope though. It turns out that the dialog supports uris, thus as long as I can give it uri which is a bookmark to a vcard representation we’re golden. </p>

<p>This is where in the past it gets a bit hairy with WCF. Today to do this means I need to ensure that my UriTemplate has a variable i.e. {id} is fine, but then I have to parse that ID to pull out the extension. It’s ugly code point blank. Jon Galloway expressed his distaste for this approach (which I suggested as a shortcut) in his post <a href="http://weblogs.asp.net/jgalloway/archive/2010/12/01/wcf-mediatypeprocessor-speech-api-speechprocessor-fun.aspx">here</a> (see the section Un-bonus: anticlimactic filename extension filtering epilogue).</p>

<p>In that post, I showed parsing the ID inline. See the ugly code in bold?</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">[WebGet(UriTemplate = &quot;<span style="color: #8b0000">{id}</span>&quot;)] 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> Contact Get(<span style="color: #0000ff">string</span> id, HttpResponseMessage response) 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{ 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><strong>    <span style="color: #0000ff">int</span> contactID = !id.Contains(&quot;<span style="color: #8b0000">.</span>&quot;)  
</strong></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><strong>        ? <span style="color: #0000ff">int</span>.Parse(id, CultureInfo.InvariantCulture)  
</strong></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><strong>        : <span style="color: #0000ff">int</span>.Parse(id.Substring(0, id.IndexOf(&quot;<span style="color: #8b0000">.</span>&quot;)), 
</strong></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><strong>        CultureInfo.InvariantCulture); 
</strong></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    var contact = <span style="color: #0000ff">this</span>.repository.Get(contactID); 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">if</span> (contact == <span style="color: #0000ff">null</span>) 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    { 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        response.StatusCode = HttpStatusCode.NotFound; 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        response.Content = HttpContent.Create(&quot;<span style="color: #8b0000">Contact not found</span>&quot;); 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    } 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">return</span> contact; 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>Actually that only solves part of the problem as I still need the Accept header to contain the media type or our content negotiation will never invoke the VCardProcessor!</p>

<h1>Another processor to the rescue</h1>

<p>Processors are one of the swiss army knives in our Web Api. We can use processors to do practically whatever we want to an HTTP request or response before it hits our operation. That means we can create a processor that automatically rips the extension out of the uri so that the operation doesn’t have to handle it as in above, and we can make it automatically set the accept header based on mapping the extension to the appropriate accept header.</p>

<p>And here’s how it is done, enter UriExtensionProcessor.</p>

<pre><pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> UriExtensionProcessor : 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   Processor&lt;HttpRequestMessage, Uri&gt;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">private</span> IEnumerable&lt;Tuple&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;&gt; extensionMappings;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> UriExtensionProcessor(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">      IEnumerable&lt;Tuple&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;&gt; extensionMappings)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">this</span>.extensionMappings = extensionMappings;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">this</span>.OutArguments[0].Name = HttpPipelineFormatter.ArgumentUri;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> ProcessorResult&lt;Uri&gt; OnExecute(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">      HttpRequestMessage httpRequestMessage)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        var requestUri = httpRequestMessage.RequestUri.OriginalString;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        var extensionPosition = requestUri.IndexOf(&quot;<span style="color: #8b0000">.</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">if</span> (extensionPosition &gt; -1)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var extension = requestUri.Substring(extensionPosition + 1);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var query = httpRequestMessage.RequestUri.Query;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            requestUri = <span style="color: #0000ff">string</span>.Format(&quot;<span style="color: #8b0000">{0}?{1}</span>&quot;, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                requestUri.Substring(0, extensionPosition), query);;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var mediaType = extensionMappings.Single(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                map =&gt; extension.StartsWith(map.Item1)).Item2;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var uri = <span style="color: #0000ff">new</span> Uri(requestUri);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            httpRequestMessage.Headers.Accept.Clear();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            httpRequestMessage.Headers.Accept.Add(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                <span style="color: #0000ff">new</span> MediaTypeWithQualityHeaderValue(mediaType));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var result = <span style="color: #0000ff">new</span> ProcessorResult&lt;Uri&gt;();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            result.Output = uri;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">return</span> result;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> ProcessorResult&lt;Uri&gt;();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>Here is how it works (note how this is done will change in future bits but the concept/appoach will be the same). </p>

<ul>
  <li>First UrlExtensionProcessor takes a collection of Tuples with the first value being the extension and the second being the media type. </li>

  <li>The output argument is set to the key “Uri”. This is because in the current bits the UriTemplateProcessor grabs the Uri to parse it. This processor will replace it. </li>

  <li>In OnExecute the first thing we do is look to see if the uri contains a “.”. <strong>Note: This is a simplistic implementation which assumes the first “.” is the one that refers to the extension. A more robust implementation would look after the last uri segment at the first dot. I am lazy, sue me. </strong></li>

  <li>Next strip the extension and create a new uri. Notice the query string is getting tacked back on. </li>

  <li>Then do a match against the mappings passed in to see if there is an extension match. </li>

  <li>If there is a match, set the accept header to use the associated media type for the extension. </li>

  <li>Return the new uri. </li>
</ul>

<p>With our new processors in place, we can now register them in the ContactManagerConfiguration class first for the request.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> RegisterRequestProcessorsForOperation(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   HttpOperationDescription operation, IList&lt;Processor&gt; processors,
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   MediaTypeProcessorMode mode)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    var map = <span style="color: #0000ff">new</span> List&lt;Tuple&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;&gt;();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    map.Add(<span style="color: #0000ff">new</span> Tuple&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;(&quot;<span style="color: #8b0000">vcf</span>&quot;, &quot;<span style="color: #8b0000">text/directory</span>&quot;));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    processors.Insert(0, <span style="color: #0000ff">new</span> UriExtensionProcessor(map));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>Notice above that I am inserting the UriExtensionProcessor first. This is to ensure that the parsing happens BEFORE the UriTemplatePrcoessor executes.</p>

<p>And then we can register the new VCardProcessor for the response.</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> RegisterResponseProcessorsForOperation(
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   HttpOperationDescription operation, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   IList&lt;Processor&gt; processors, 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   MediaTypeProcessorMode mode)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    processors.Add(<span style="color: #0000ff">new</span> PngProcessor(operation, mode));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><strong>    processors.Add(<span style="color: #0000ff">new</span> VCardProcessor(operation));
</strong></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<h1>Moment of truth – testing Outlook</h1>

<p>Now with everything in place we “should” be able to import a contact into Outlook. First we have Outlook before the contact has been imported. I’ll use Jeff Handley as the guinea pig. Notice below when I search through my contacts he is NOT there.</p>

<p>&#160;</p>
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/6320.image_3D1F6314.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/6320.image_5F00_3D1F6314.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4452.image_thumb_2C57B866.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/4452.image_5F00_thumb_5F00_2C57B866.png" width="438" height="261" /></a> 

<p>Now after launching the ContactManager, I will go to the File-&gt;Open-&gt;Import dialog, and choose to import .vcf.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/3113.image_4F580409.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/3113.image_5F00_4F580409.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/4300.image_thumb_230B5758.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/4300.image_5F00_thumb_5F00_230B5758.png" width="440" height="262" /></a></p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/7345.image_4677D5F0.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/7345.image_5F00_4677D5F0.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/8831.image_thumb_785F50AD.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/8831.image_5F00_thumb_5F00_785F50AD.png" width="422" height="269" /></a></p>

<p>Click ok, and then refresh the search. Here is what we get.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/6371.image_47D8A66A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/6371.image_5F00_47D8A66A.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/7853.image_thumb_39B9B76D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/7853.image_5F00_thumb_5F00_39B9B76D.png" width="441" height="263" /></a></p>

<h1></h1>

<h1>What we’ve learned</h1>

<ul>
  <li>Applying a RESTful style allows us evolve our application to support a new vcard representation. </li>

  <li>Using representations allows us to integrate with a richer set of clients such as Outlook and ACT. </li>

  <li>WCF Web APIs allows us to add support for new representations <em>without </em>modifying the resource handler code (ContactResource) </li>

  <li>We can use processors for a host of HTTP related concerns including mapping uri extensions as bookmarks to variant representations. </li>

  <li>WCF Web APIs is pretty cool <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/2260.wlEmoticon-smile_07FE9A18.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/2260.wlEmoticon_2D00_smile_5F00_07FE9A18.png" /> </li>
</ul>

<p>I will post the code. For now you can copy paste the code and follow my direction using the ContactManager. It will work <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/73/92/metablogapi/2260.wlEmoticon-smile_07FE9A18.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-73-92-metablogapi/2260.wlEmoticon_2D00_smile_5F00_07FE9A18.png" /></p>

<h1><strong>What’s next.</strong> </h1>

<p>In the next post I will show you how to use processors to do a redirect or set the content-location header.</p>]]></content:encoded>
    </item>
    <item>
      <title>WCF Web APIs Roundup–Volume 2</title>
      <link>https://review.docs.microsoft.com/archive/blogs/gblock/wcf-web-apis-roundupvolume-2</link>
      <pubDate>Sun, 06 Mar 2011 16:37:52 GMT</pubDate>
      <dc:creator><![CDATA[The Real Glenn Block]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gblock/2011/03/06/wcf-web-apis-roundupvolume-2/</guid>
      <description><![CDATA[Been a while since our last roundup and since my last blog post for that matter! Fortunately there’s...]]></description>
      <content:encoded><![CDATA[<p>Been a while since our last roundup and since my last blog post for that matter! Fortunately there’s been a bunch of cool stuff going on in the community with our Web APIs that I can point you to. Great to see the community momentum pick up as we cross the 5000 download mark on <a href="http://wcf.codeplex.com">Codeplex</a>!</p>  <h1>Blogs</h1>  <ul>   <ul><!--EndFragment--></ul>    <li><strong>WCF Web API general</strong></li>    </ul><ul>     <li><a href="http://wizardsofsmart.net/news/a-new-web-for-net-wcf-web-apis/">A new Web for .NET: WCF Web APIs</a> – Ryan Riley talks about the new Web APIs and work he is doing in F# to offer a Sinatra like experience using them. </li>      <li><a href="http://thegsharp.wordpress.com/2011/02/16/wcf-http-start-using-it/">WCF HTTP – Start Using It</a> – Gustavo walks through the basics of setting up an HTTP Service and adding Media Type support.</li>   </ul>    <ul><li><strong>HttpClient</strong></li>    </ul><ul>     <li><a title="http://www.theleagueofpaul.com/url-shortening-with-wcf-web-api-httpclient" href="http://www.theleagueofpaul.com/url-shortening-with-wcf-web-api-httpclient">Url shortening with WCF Web Apis HttpClient</a> - Paul Jenkins of <a href="http://www.mahtweets.com/">MahTweets</a> fame posts on using our new Http client API for calling a url shortening service </li>      <li><a href="http://xamlcoder.com/blog/2011/01/23/consuming-wcf-web-rest-apis-in-silverlight/">Consuming WCF Web (REST) Apis in Silverlight</a> – Joe Mcbride blogs about a new SimpleHttpClient he created for accessing WCF Web API services and other services. </li>   </ul>    <ul><li><strong>Processors</strong></li>    </ul><ul>     <li><a href="http://thegsharp.wordpress.com/2011/02/17/wcf-http-processors-under-the-hood/">WCF HTTP – Processors under the hood</a> – Gustavo gives a deep overview of how processors work. He also shows how to build several processors including a processor that will convert uri parameters into native types.</li>      <li><a href="http://wizardsofsmart.net/news/middleware-in-the-wcf-web-apis/">Middleware in the WCF Web APIs</a> – Ryan posts on how you can use our new Processor api for plugging in Middleware like different view engines.</li>      <li><a href="http://www.funnelweblog.com/extensions/wcf-http-extensions">Extensions – WCF HTTP Services</a> – Funnel Web is an OSS blog <a href="http://www.funnelweblog.com/">engine</a>. This post shows you how you can plug in services which are hosted in FunnelWeb and which have DI support through Autofac via the new IoC extensions in Preview 3.</li>      <li><a href="http://thegsharp.wordpress.com/2011/02/17/wcf-http-cool-processor-for-enabling-navigation/">WCF HTTP – Cool processor for Navigation</a> – Gustavo shows us how a custom processor can simplify handling sub-resources.</li>   </ul>    <ul><li><strong>Security</strong></li>    </ul><ul>     <li><a href="http://weblogs.asp.net/cibrax/archive/2011/02/04/authenticating-clients-in-the-new-wcf-http-stack.aspx">Authenticating clients in the WCF HTTP Stack</a> – In this Pablo Cibraro introduces some extensions for WCF Web APIs based on previous interceptors he had for the REST Start Kit which are used for authenticating clients. He says he believes the new Web APIs offer much richer support for building HTTP oriented services in NET. We agree :-)</li>      <li><a href="http://blog.alexonasp.net/post/2011/03/02/Using-WCF-Web-APIs-WCF-Http-with-ASPNET-Forms-Authentication.aspx">Using WCF Web APIs / WCF Http with ASP.NET Forms Authentication</a> – Alex Zeitler shows us how to use WCF Web APIs with ASP.NET forms authentication!</li>   </ul>    <ul><li><strong>ASP.NET MVC</strong></li>    </ul><ul>     <li><a href="http://pozitive.net/2011/02/11/json-asp-net-mvc-and-jquery-working-with-untyped-json-made-easy/">JSON, ASP.NET MVC and JQuery – Working with Untyped JSON made easy</a> – Ana posts on how you can access untyped Json via a custom model binder in MVC which uses the new JsonValue that we ship in WCF Web APIs </li> </ul><!--EndFragment-->   <h1>Podcasts / Videos</h1>  <ul>   <li><a href="https://channel9.msdn.com/Series/mvcConf/mvcConf-2-Glenn-Block-Take-some-REST-with-WCF">Take some REST with WCF</a> – My talk at MVCConf on our new APIs including exposing OData, and usage with MVC.</li>    <li><a href="https://channel9.msdn.com/Shows/Endpoint/endpointtv-WCF-Web-API-Content-Types">endpoint.tv – WCF Web API – Content Types</a> – Ron Jacobs and I look at the new media type support in WCF Web APIs which enables building great browser apps that use JQuery to talk to HTTP Services.</li>    <li><a href="http://jesseliberty.com/2011/02/22/yet-another-podcast-25glenn-block-wcf/">Yet Another Podcast #25-Glenn Block/WCF</a> – Jesse Liberty and I kick it about HTTP, REST and the new Web APIs. That is after I finish interviewing him. :p</li> </ul>  <h1>WCF Web API team</h1>  <ul>   <li><a href="http://codebetter.com/howarddierking/2011/03/02/ive-moved-3/">I’ve moved</a> – Howard Dierking (formerly of MSDN Magazine) announces that he has joined our team!</li> </ul>]]></content:encoded>
    </item>
  </channel>
</rss>