<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Scott Seely</title><subtitle type="html" /><id>http://devlicio.us/blogs/scott_seely/atom.aspx</id><link rel="alternate" type="text/html" href="http://devlicio.us/blogs/scott_seely/default.aspx" /><link rel="self" type="application/atom+xml" href="http://devlicio.us/blogs/scott_seely/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2010-04-30T00:00:00Z</updated><entry><title>Developer Smackdown show</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2011/05/05/developer-smackdown-show.aspx" /><id>/blogs/scott_seely/archive/2011/05/05/developer-smackdown-show.aspx</id><published>2011-05-05T21:26:00Z</published><updated>2011-05-05T21:26:00Z</updated><content type="html">&lt;p&gt;I was recently on the Developer Smackdown podcast with Clark Sell, Mark Nichols, and Glenn Block. We spent an hour talking REST and WCF over at MIX. The show came out really good! Thanks for having me on again, Clark! Check out show #47: &lt;a href="http://developersmackdown.com/Archives/Show/47"&gt;http://developersmackdown.com/Archives/Show/47&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67221" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>PDC 10 Local Coming to Chicago/Milwaukee</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/10/22/pdc-10-local-coming-to-chicago-milwaukee.aspx" /><id>/blogs/scott_seely/archive/2010/10/22/pdc-10-local-coming-to-chicago-milwaukee.aspx</id><published>2010-10-22T16:01:00Z</published><updated>2010-10-22T16:01:00Z</updated><content type="html">&lt;p class="MsoNormal"&gt;&lt;a href="http://www.microsoftpdc.com/"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;Microsoft PDC 10&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt; is just around the corner! Expect to hear announcements about Visual Studio 2010, Windows Phone 7, and Windows Azure as well as other major announcements. Starting October 28, you will be hearing about many new things coming from Microsoft. If you aren&amp;#39;t there in person, the whole experience may be less than satisfying. To boost the experience when watching closer to home, wouldn&amp;#39;t it be better to watch the keynotes with a bunch of fellow developers? Of course it would! We have a few events planned post PDC 10 to check out the keynotes in the AM, then dive into the big technologies in the afternoon. Please come join us!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032466051&amp;amp;Culture=en-US"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;Nov 5, all day, Waukesha, WI&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032466052&amp;amp;Culture=en-US"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;Nov 11, all day, Downers Grove, IL&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=62990" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Clean paths with WCF Hosted Workflows</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/09/08/clean-paths-with-wcf-hosted-workflows.aspx" /><id>/blogs/scott_seely/archive/2010/09/08/clean-paths-with-wcf-hosted-workflows.aspx</id><published>2010-09-08T22:20:00Z</published><updated>2010-09-08T22:20:00Z</updated><content type="html">&lt;p&gt;I am a big fan of the things added to WCF 4.0. One of those things is the deep integration with ASP.NET routes. Today, I was writing a service in WF and hosting the workflow with WCF. I really didn’t like the service URL—yeah, I’m a picky developer who doesn’t like exposing implementation details in the URL. &lt;/p&gt;  &lt;p&gt;I knew a few things:&lt;/p&gt;  &lt;p&gt;1. WF/WCF integration provides a ServiceHostFactory named WorkflowServiceHostFactory for hosting XAMLX files in WCF.&lt;/p&gt;  &lt;p&gt;2. WorfklowServiceHostFactory will see CreateServiceHost called with some constructorString plus a bunch of baseAddresses.&lt;/p&gt;  &lt;p&gt;3. I wanted the host to work on HTTP only—I don’t care about goofy URLs for net.tcp.&lt;/p&gt;  &lt;p&gt;4. XAMLX services do not have a runtime defined type- they exist only in XAML.&lt;/p&gt;  &lt;p&gt;My goal was to create a new route type, like ServiceRoute, that allowed me to pass in the desired path and the path to the XAMLX to instantiate. After a few minutes of thinking and hacking, I had the following:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowServiceRoute &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;ServiceRoute
&lt;/span&gt;{
  &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HostedWorkflowServiceHostFactory &lt;/span&gt;: &lt;/pre&gt;

&lt;pre class="code"&gt;    &lt;span style="color:#2b91af;"&gt;WorkflowServiceHostFactory
  &lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;HostedWorkflowServiceHostFactory(&lt;span style="color:blue;"&gt;string &lt;/span&gt;xamlxPath)
    {
      XamlxPath = xamlxPath;
    }

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;XamlxPath { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public override &lt;/span&gt;System.ServiceModel.&lt;span style="color:#2b91af;"&gt;ServiceHostBase &lt;/span&gt;CreateServiceHost(
      &lt;span style="color:blue;"&gt;string &lt;/span&gt;constructorString, &lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;[] baseAddresses)
    {
      &lt;span style="color:blue;"&gt;return base&lt;/span&gt;.CreateServiceHost(XamlxPath, baseAddresses);
    }
  }

  &lt;span style="color:blue;"&gt;public &lt;/span&gt;WorkflowServiceRoute(&lt;span style="color:blue;"&gt;string &lt;/span&gt;routePrefix, &lt;span style="color:blue;"&gt;string &lt;/span&gt;xamlxPath)
    : &lt;span style="color:blue;"&gt;base&lt;/span&gt;(routePrefix, &lt;/pre&gt;

&lt;pre class="code"&gt;           &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HostedWorkflowServiceHostFactory&lt;/span&gt;(xamlxPath), &lt;/pre&gt;

&lt;pre class="code"&gt;           &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;object&lt;/span&gt;))
  {
  }
}&lt;/pre&gt;

&lt;p&gt;I’m pretty happy with the succinctness of the class and the fact that it works on the few use cases I have at hand. Requests are directed to the correct locations and integration seems to be just fine. Use of the WorkflowServiceRoute is just:&lt;/p&gt;

&lt;pre class="code"&gt;routes.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowServiceRoute&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;helloWorld&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;SimpleWorkflow.xamlx&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

&lt;p&gt;Frankly, this is the first implementation I thought to write, and it works. The code size is small. I don’t like a few things about it, but I’ll live. Things I don’t like:&lt;/p&gt;

&lt;p&gt;1. Passing typeof(object) to the base constructor from the route seems wrong. The receiver code thinks it needs a reference to the service type at all times. I’m just lying to the ServiceRoute so that I can take advantage of everything good about it.&lt;/p&gt;

&lt;p&gt;2. Custom ServiceHost just so the code can remember the path to the XAMLX. This bothers me until I think that this is the same thing that happens with each .SVC or other XAMLX file. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;As a benefit, I get URLs that look like this:&lt;/p&gt;

&lt;pre&gt;http://scottseely-xps/WfHostApp/helloWorld&lt;br /&gt;&lt;font size="3" face="Arial"&gt;instead of:&lt;/font&gt;&lt;/pre&gt;

&lt;pre&gt;&amp;#160;&lt;/pre&gt;

&lt;pre&gt;http://scottseely-xps/WfHostApp/SimpleWorkflow.xamlx&lt;/pre&gt;

&lt;pre&gt;&lt;br /&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;This serves as yet another example of how good it is that WCF is super extensible and what a great design decision it was to build WCF on top of the extensibility points instead of along side them.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=61953" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>How JSONP works (and some bits about implementing it in WCF)</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/09/07/how-jsonp-works-and-some-bits-about-implementing-it-in-wcf.aspx" /><id>/blogs/scott_seely/archive/2010/09/07/how-jsonp-works-and-some-bits-about-implementing-it-in-wcf.aspx</id><published>2010-09-07T13:00:00Z</published><updated>2010-09-07T13:00:00Z</updated><content type="html">&lt;p&gt;In the world of the web, we have lots of security concerns. One of the concerns lies with cross site scripting, XSS. From a high level, XSS is any occasion where data is sent from code on a page from one site to another site. The code is usually via JavaScript, though flash and Silverlight are included in the terminology and mitigations. One way around this that is generally viewed as safe is JSON with Padding, aka JSONP. The way JSONP works is this: you pass an HTTP GET request to retrieve a resource from another site which you do not control. The request contains two pieces of information: &lt;/p&gt;
&lt;p&gt;1. The resource you want to retrieve.&lt;/p&gt;
&lt;p&gt;2. The callback function that should be executed when the resource is returned.&lt;/p&gt;
&lt;p&gt;What makes this safe? The callback function is always something that you control. It is assumed that if your callback does bad things, so be it; that problem existed without involving JSONP. &lt;/p&gt;
&lt;p&gt;There is a convention around JSONP. The URL that you call needs to understand a querystring parameter named &lt;em&gt;callback&lt;/em&gt;, which identifies the function to call when the method returns. How does this work? Assume we have a resource that, when no callback is specified, returns the following when requesting the resource at &lt;/p&gt;
&lt;p&gt;http://localhost/WcfJsonp/jsonp/names:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;[{&amp;quot;FirstName&amp;quot;:&amp;quot;Scott&amp;quot;,&amp;quot;LastName&amp;quot;:&amp;quot;Seely&amp;quot;},&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;{&amp;quot;FirstName&amp;quot;:&amp;quot;Aaron&amp;quot;,&amp;quot;LastName&amp;quot;:&amp;quot;Skonnard&amp;quot;},&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;{&amp;quot;FirstName&amp;quot;:&amp;quot;Matt&amp;quot;,&amp;quot;LastName&amp;quot;:&amp;quot;Milner&amp;quot;}]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;With JSONP, we would like a GET of the above data to execute a function on our page named &lt;em&gt;updatePeople&lt;/em&gt;. JSONP indicates that we do this with a request for the resource at http://localhost/WcfJsonp/jsonp/names?callback=updatePeople. In so doing, the resource is now returned as:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;updatePeople(&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;[{&amp;quot;FirstName&amp;quot;:&amp;quot;Scott&amp;quot;,&amp;quot;LastName&amp;quot;:&amp;quot;Seely&amp;quot;},&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp; {&amp;quot;FirstName&amp;quot;:&amp;quot;Aaron&amp;quot;,&amp;quot;LastName&amp;quot;:&amp;quot;Skonnard&amp;quot;},&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp; {&amp;quot;FirstName&amp;quot;:&amp;quot;Matt&amp;quot;,&amp;quot;LastName&amp;quot;:&amp;quot;Milner&amp;quot;}]);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This causes the function, updatePeople, to be called as soon as the resource is retrieved. &lt;/p&gt;
&lt;p&gt;How does this work? Most of us will use jQuery to get the job done and not think about things. But, without jQuery, JSONP is still possible. I&amp;rsquo;ll first show you how this works by hand, then with jQuery. jQuery eliminates a number of potential bugs, so I recommend reading the by hand portion solely to understand things&amp;mdash;don&amp;rsquo;t implement it in production code!&lt;/p&gt;
&lt;p&gt;Assume you have the following HTML body:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;input &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;button&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;onclick&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;getPeopleJsonp();&amp;quot; &lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Get people&amp;quot; /&amp;gt;  
    &amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;people&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text/javascript&amp;quot; &lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;      &lt;/span&gt;&lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;/wcfjsonp/Scripts/jquery-1.4.1.min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
&lt;/span&gt;        &lt;span style="color:blue;"&gt;function &lt;/span&gt;updatePeople(data) {
          &lt;span style="color:blue;"&gt;var &lt;/span&gt;innerHtml = &lt;span style="color:maroon;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
          &lt;span style="color:blue;"&gt;for &lt;/span&gt;(i = 0; i &amp;lt; data.length; ++i) {
            innerHtml += data[i].FirstName + &lt;span style="color:maroon;"&gt;&amp;#39; &amp;#39; &lt;/span&gt;+ &lt;/pre&gt;
&lt;pre class="code"&gt;                         data[i].LastName + &lt;span style="color:maroon;"&gt;&amp;#39;&amp;lt;br/&amp;gt;&amp;#39;&lt;/span&gt;;
          }
          $(&lt;span style="color:maroon;"&gt;&amp;quot;#people&amp;quot;&lt;/span&gt;).html(innerHtml);
        }

        &lt;span style="color:blue;"&gt;function &lt;/span&gt;getPeopleJsonp() {
          &lt;span style="color:blue;"&gt;var &lt;/span&gt;innerHtml = &lt;span style="color:maroon;"&gt;&amp;quot;&amp;lt;script type=&amp;#39;text/javascript&amp;#39; &amp;quot; &lt;/span&gt;+ &lt;/pre&gt;
&lt;pre class="code"&gt;                          &lt;span style="color:maroon;"&gt;&amp;quot;src=&amp;#39;http://scottseely-xps/wcfjsonp/&amp;quot; &lt;span style="color:#000000;"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:maroon;"&gt;                          &lt;span style="color:maroon;"&gt;&amp;quot;&lt;/span&gt;jsonp/names?callback=updatePeople&amp;#39;&amp;gt;&amp;lt;\/script&amp;gt;&amp;quot;&lt;/span&gt;;
          $(&lt;span style="color:maroon;"&gt;&amp;quot;#inject&amp;quot;&lt;/span&gt;).html(innerHtml);
        }
    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;inject&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;What is happening here? When someone clicks on the button, the page calls getPeopleJsonp. That code updates the content of the div whose id is &lt;em&gt;inject&lt;/em&gt; to contain a script tag. The script tag points to a JSONP endpoint and passes the callback parameter indicating to call the function updatePeople upon success. That script is then evaluated, executes a local JavaScript function, and returns. Every time that same script is reinjected, the same behavior occurs.&lt;/p&gt;
&lt;p&gt;Now, jQuery provides a more succinct mechanism for doing the same thing. Instead of having the previous two functions and updating the DOM ourselves, we would write this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;function &lt;/span&gt;getPeopleJquery() {
  $.ajax({
    dataType: &lt;span style="color:maroon;"&gt;&amp;#39;jsonp&amp;#39;&lt;/span&gt;,
    url: &lt;span style="color:maroon;"&gt;&amp;quot;http://scottseely-xps/WcfJsonp/jsonp/names&amp;quot;&lt;/span&gt;,
    success: &lt;span style="color:blue;"&gt;function &lt;/span&gt;(data) {
      &lt;span style="color:blue;"&gt;var &lt;/span&gt;innerHtml = &lt;span style="color:maroon;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
      &lt;span style="color:blue;"&gt;for &lt;/span&gt;(i = 0; i &amp;lt; data.length; ++i) {
        innerHtml += data[i].FirstName + &lt;span style="color:maroon;"&gt;&amp;#39; &amp;#39; &lt;/span&gt;+ data[i].LastName + &lt;span style="color:maroon;"&gt;&amp;#39;&amp;lt;br/&amp;gt;&amp;#39;&lt;/span&gt;;
      }
      $(&lt;span style="color:maroon;"&gt;&amp;quot;#people&amp;quot;&lt;/span&gt;).html(innerHtml);
    }
  });
}&lt;/pre&gt;
&lt;p&gt;The code to inject information into the DOM still occurs, as does the creation of a callback function. What jQuery does is it adds script tag to the DOM only until the callback (success function) is done executing. The tag is added to the header. It also adds a function to the window object which is called on return. The URL jQuery constructs looks like http://localhost/WcfJsonp/jsonp/names?callback=jsonp1283609644773. What it actually does is add the following:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scott_5F00_seely/blogtagadded_5F00_7DEA95AD.png"&gt;&lt;img height="195" width="583" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scott_5F00_seely/blogtagadded_5F00_thumb_5F00_1B7C70AD.png" alt="blog-tagadded" border="0" title="blog-tagadded" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Within the window object, a new function is added:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scott_5F00_seely/expandos_5F00_7AA887F8.png"&gt;&lt;img height="194" width="589" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/scott_5F00_seely/expandos_5F00_thumb_5F00_32E6FF11.png" alt="expandos" border="0" title="expandos" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;jsonp1283609644773 is just an object living on the window object and is a dynamically added function. When the function is done executing, it will remove itself from the window object, leaving a slot by the same name with a value of &lt;em&gt;undefined&lt;/em&gt;. What does the function look like when it is alive? &lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;font-size:x-small;"&gt;function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&amp;amp;&amp;amp;A.removeChild(B)}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So, yeah, not too intelligible, but it does appear to handle things just fine. b(), d(), and the other functions are all part of the minified jQuery library, meaning that it all makes sense in the context of the containing object. The call to b() is contains code to call the success function. Everything else is cleanup code (at least from what it looked like to me&amp;hellip;). To make this whole thing work in WCF, you need to do a couple simple things:&lt;/p&gt;
&lt;p&gt;1. Only use WebGet to fetch resources.&lt;/p&gt;
&lt;p&gt;2. Make sure the resource is hard-coded to respond in JSON. Otherwise, the response will appear as XML and the callback code won&amp;rsquo;t execute.&lt;/p&gt;
&lt;p&gt;3. Make sure your binding supports JSONP. &lt;/p&gt;
&lt;p&gt;4. Make sure your service requires ASP.NET compatibility.&lt;/p&gt;
&lt;p&gt;For example, to get the names, I have the following WCF code:&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;]
[&lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirements&lt;/span&gt;(
  RequirementsMode = &lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirementsMode&lt;/span&gt;.Required)]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;JsonpDemo
&lt;/span&gt;{
  [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;]
  [&lt;span style="color:#2b91af;"&gt;WebGet&lt;/span&gt;(UriTemplate = &lt;span style="color:#a31515;"&gt;&amp;quot;names&amp;quot;&lt;/span&gt;, ResponseFormat = &lt;span style="color:#2b91af;"&gt;WebMessageFormat&lt;/span&gt;.Json)]
  &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PersonName&lt;/span&gt;[] GetNames()
  {
    &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PersonName&lt;/span&gt;[]
              {
                &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PersonName &lt;/span&gt;{FirstName = &lt;span style="color:#a31515;"&gt;&amp;quot;Scott&amp;quot;&lt;/span&gt;, LastName = &lt;span style="color:#a31515;"&gt;&amp;quot;Seely&amp;quot;&lt;/span&gt;},
                &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PersonName &lt;/span&gt;{FirstName = &lt;span style="color:#a31515;"&gt;&amp;quot;Aaron&amp;quot;&lt;/span&gt;, LastName = &lt;span style="color:#a31515;"&gt;&amp;quot;Skonnard&amp;quot;&lt;/span&gt;},
                &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PersonName &lt;/span&gt;{FirstName = &lt;span style="color:#a31515;"&gt;&amp;quot;Matt&amp;quot;&lt;/span&gt;, LastName = &lt;span style="color:#a31515;"&gt;&amp;quot;Milner&amp;quot;&lt;/span&gt;}
              };
  }
}&lt;/pre&gt;
&lt;p&gt;Configuration has:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;serviceHostingEnvironment &lt;/span&gt;&lt;span style="color:red;"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;standardEndpoints&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;webHttpEndpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;standardEndpoint &lt;/span&gt;&lt;span style="color:red;"&gt;crossDomainScriptAccessEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot; 
                        &lt;span style="color:red;"&gt;automaticFormatSelectionEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;webHttpEndpoint&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;standardEndpoints&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The crossDomainScriptAccessEnabled flag turns on the ability to correctly parse and respond to the presence of the callback parameter in the query string.&lt;/p&gt;
&lt;p&gt;Finally, I added a route to handle the service within my Global.asax:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;factory = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WebServiceHostFactory&lt;/span&gt;();
routes.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceRoute&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;jsonp&amp;quot;&lt;/span&gt;, factory, &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;JsonpDemo&lt;/span&gt;)));&lt;/pre&gt;
&lt;p&gt;I was looking at the technology only to evaluate how to use it and to understand, a bit more deeply, how JSONP actually works. I found myself looking for a post that explains the magic, but most of the information I found just said &amp;ldquo;use jQuery.&amp;rdquo; Handy&amp;mdash;sure. But that didn&amp;rsquo;t help me understand all the magic goodness that jQuery was doing for me.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=61851" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Talking about REST</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/09/02/talking-about-rest.aspx" /><id>/blogs/scott_seely/archive/2010/09/02/talking-about-rest.aspx</id><published>2010-09-02T14:55:00Z</published><updated>2010-09-02T14:55:00Z</updated><content type="html">&lt;p&gt;Mark and Clark over at &lt;a target="_blank" href="http://developersmackdown.com"&gt;developersmackdown.com&lt;/a&gt; just published &amp;lsquo;my&amp;rsquo; show: &lt;a href="http://developersmackdown.com/archives/SingleShow/30" title="http://developersmackdown.com/archives/SingleShow/30"&gt;http://developersmackdown.com/archives/SingleShow/30&lt;/a&gt;. We spent time talking about REST and SOAP as well as a number of other topics related to REST. One of the things that I don&amp;rsquo;t think was made clear enough was that REST and SOAP are not competing service techniques. Each technology/interface type has an appropriate use case. When integrating applications within an enterprise, the development team needs to worry about:&lt;/p&gt;
&lt;p&gt;- Security&lt;/p&gt;
&lt;p&gt;- Transactions&lt;/p&gt;
&lt;p&gt;- Reliable delivery of messages&lt;/p&gt;
&lt;p&gt;- Integration with tooling for other developers&lt;/p&gt;
&lt;p&gt;In the enterprise case, WCF + SOAP/WS-* can make integration between systems pretty simple. Yes, the teams may struggle with getting the security setup just right between domains, but overall, things will go well, especially if the setup requires communicating between different WS-* implementations. Finally, enterprise integrations typically happen for applications running on the same network/VPN. The infrastructure for an enterprise is different than that for the web. It&amp;rsquo;s important to build your applications for their environment.&lt;/p&gt;
&lt;p&gt;When integrating applications over the Internet, sometimes WS-* adds too much complexity. For extensive integration across partners who are connected via the Internet, there is some benefit to understanding REST. REST will allow your application to scale using the HTTP architecture. Features such as caching, proxy servers, and the general uniform interface exposed by HTTP helps make things work better on the global network.&lt;/p&gt;
&lt;p&gt;Because of my point of view here, when asked &amp;ldquo;do you prefer SOAP or REST?&amp;rdquo;, I am forced to answer &amp;ldquo;For what scenario?&amp;rdquo; I&amp;rsquo;m not popular in either circle, but understanding both helps me get stuff done.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=61814" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Project Phoenix</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/08/19/project-phoenix.aspx" /><id>/blogs/scott_seely/archive/2010/08/19/project-phoenix.aspx</id><published>2010-08-19T13:30:00Z</published><updated>2010-08-19T13:30:00Z</updated><content type="html">&lt;p&gt;The current economic condition is hitting everyone pretty hard, even developers. For developers, part of the challenge in finding that next job is having the right, up to date skills. To help folks get those skills, &lt;a target="_blank" href="http://sqlblog.com/blogs/arnie_rowland/"&gt;Arnie Rowland&lt;/a&gt; and a number of other MVPs got together to pool MSDN subscriptions. This year, every MVP gets 3 MSDN Universal Subscriptions- 1 to use and 2 to give to worthy recipients. To pick a worthy recipient, an unemployed or underemployed developer needs to propose a software project for a non-profit agency, school, or church to be assisted by &lt;a target="_blank" href="http://sqlblog.com/blogs/arnie_rowland/archive/2010/07/30/like-a-phoenix-rising-from-the-ashes.aspx"&gt;Project Phoenix&lt;/a&gt;. Arnie and his associates will then pick at least one project week to &amp;lsquo;fund&amp;rsquo; with the MSDN Universal Subscription. A number of other companies joined in to offer more resources to help the selected developers make the most of this opportunity. Publishers have donated books and software companies have donated tools. I&amp;rsquo;m very proud that Pluralsight has donated a subscription to their .NET Training Library. I have created content for that library and am thrilled that an organization I am involved with is helping developers get back up to speed with current technology. &lt;/p&gt;
&lt;p&gt;Project Phoenix is not a &amp;lsquo;free lunch.&amp;rsquo; It supports the developers&amp;rsquo; efforts so that they can gain from the work they do. I do recommend that you visit &lt;a target="_blank" href="http://sqlblog.com/blogs/arnie_rowland/archive/2010/07/30/like-a-phoenix-rising-from-the-ashes.aspx"&gt;Arnie&amp;rsquo;s site&lt;/a&gt; to read all the details! &lt;/p&gt;
&lt;p&gt;Here is the an example of one project that was funded:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Feed My Sheep&lt;/strong&gt;: We are a community feeding program, that originally started as a 3 month summer project, one night a week we would provide a free meal for anyone who wanted to attend. We are in desperate need of a website in which we could post updates, have a calendar of volunteers and groups that will be serving each month and list special events.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=61546" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Azure Storage is a RESTful service</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/06/25/azure-storage-is-a-restful-service.aspx" /><id>/blogs/scott_seely/archive/2010/06/25/azure-storage-is-a-restful-service.aspx</id><published>2010-06-25T13:09:00Z</published><updated>2010-06-25T13:09:00Z</updated><content type="html">&lt;p&gt;Today I had to build a demo for Azure and I noticed that I was following a tired old path where one demonstrates Azure storage services (Table/Queue/Blob) via a hosted application. My demo has two key points: &lt;/p&gt;
&lt;p&gt;1. Look, there&amp;rsquo;s a picture that I uploaded!&lt;/p&gt;
&lt;p&gt;2. Look, these processes can send messages via the queue!&lt;/p&gt;
&lt;p&gt;The kicker was going to be that the messages are exchanged over the Internet, not the demo environment. I wanted a visible resource, an image of penguins, to be visible via a public URL. That was going to be the cool part.Then, I thought- &amp;ldquo;Well, the Azure SDK is just a bunch of libraries. The libraries should work fine in a console application, right?&amp;rdquo; Right!&amp;nbsp; &lt;/p&gt;
&lt;p&gt;And guess what: the demo actually works pretty slick because I can demo the storage service in isolation. I don&amp;rsquo;t need to demo it with a deployed application. That helps me out, and gives me some ideas on how I can use Azure differently. &lt;/p&gt;
&lt;p&gt;I started out with a little utility class that reads a connection string from a config file and returns a ready to use &lt;code&gt;CloudStorageAccount&lt;/code&gt; instance. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Utility
&lt;/span&gt;{
  &lt;span style="color:blue;"&gt;private static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CloudStorageAccount &lt;/span&gt;_account;

  &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CloudStorageAccount &lt;/span&gt;StorageAccount
  {
    &lt;span style="color:blue;"&gt;get
    &lt;/span&gt;{
      &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_account == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
      {
        _account = &lt;span style="color:#2b91af;"&gt;CloudStorageAccount&lt;/span&gt;.Parse(
          &lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color:#a31515;"&gt;&amp;quot;storageAccount&amp;quot;&lt;/span&gt;]);
      }
      &lt;span style="color:blue;"&gt;return &lt;/span&gt;_account;
    }
  }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The config is just the following (minus the line breaks in the &amp;lsquo;value&amp;rsquo; value):&lt;/p&gt;
&lt;pre class="code"&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;appSettings&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add &lt;/span&gt;&lt;span style="color:red;"&gt;key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;storageAccount&lt;/span&gt;&amp;quot; 
         &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;DefaultEndpointsProtocol=https;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;                AccountName=[your account name];&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;                AccountKey=[your account key]&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;appSettings&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;My scenario is this: I have a directory with images. I want to force those images to be uploaded to Azure blob storage. This needs to happen from the local machine. I was really surprised how easy this is to do. The Microsoft.WindowsAzure.StorageClient assembly has all the code you need to make this work. To upload the images and make them visible to the public, I just wrote the following:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main()
{
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;client = &lt;span style="color:#2b91af;"&gt;Utility&lt;/span&gt;.StorageAccount.CreateCloudBlobClient();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;dirInfo = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DirectoryInfo&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.CurrentDirectory);
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;cloudContainer = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CloudBlobContainer&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;friseton&amp;quot;&lt;/span&gt;, client);
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;permissions = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;BlobContainerPermissions
                      &lt;/span&gt;{
                        PublicAccess = &lt;span style="color:#2b91af;"&gt;BlobContainerPublicAccessType&lt;/span&gt;.Blob
                      };
  cloudContainer.CreateIfNotExist();
  cloudContainer.SetPermissions(permissions);
  &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;fileInfo &lt;span style="color:blue;"&gt;in &lt;/span&gt;dirInfo.EnumerateFiles(&lt;span style="color:#a31515;"&gt;&amp;quot;*.jpg&amp;quot;&lt;/span&gt;))
  {
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;blobRef = cloudContainer.GetBlobReference(fileInfo.Name);
    blobRef.DeleteIfExists();
    blobRef.UploadFile(fileInfo.FullName);
  }
}&lt;/pre&gt;
&lt;p&gt;In this way, you can use Azure blob storage the same way you use Amazon&amp;rsquo;s &lt;a target="_blank" href="http://aws.amazon.com/s3/"&gt;S3&lt;/a&gt;. The queue can be used like the &lt;a target="_blank" href="http://aws.amazon.com/sqs/"&gt;Simple Queue Service&lt;/a&gt;, and table can be accessed liked &lt;a target="_blank" href="http://aws.amazon.com/simpledb/"&gt;SimpleDB&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, I understand that this has been possible for Azure all along. It finally clicked in my noggin that developing for Azure really can mean just picking and choosing the parts you want to use. You don&amp;rsquo;t need to go all in to use the service. Instead, just pick the parts that make sense and build apps!&lt;/p&gt;
&lt;p&gt;For those that are curious, here is the queue demo too. It uses an object, Name, to send messages. This could be ANY object, I just picked something simple for demo purposes.&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;DataContract&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Name
&lt;/span&gt;{
  [&lt;span style="color:#2b91af;"&gt;DataMember&lt;/span&gt;]
  &lt;span style="color:blue;"&gt;public string &lt;/span&gt;FirstName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

  [&lt;span style="color:#2b91af;"&gt;DataMember&lt;/span&gt;]
  &lt;span style="color:blue;"&gt;public string &lt;/span&gt;LastName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;It is sent to the queue with this code:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main()
{
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;client = &lt;span style="color:#2b91af;"&gt;Utility&lt;/span&gt;.StorageAccount.CreateCloudQueueClient();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;cloudQueue = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CloudQueue&lt;/span&gt;(
    &lt;span style="color:#2b91af;"&gt;Utility&lt;/span&gt;.StorageAccount.QueueEndpoint + &lt;span style="color:#a31515;"&gt;&amp;quot;friseton&amp;quot;&lt;/span&gt;, 
    client.Credentials);
  cloudQueue.CreateIfNotExist();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;name = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Name &lt;/span&gt;{FirstName = &lt;span style="color:#a31515;"&gt;&amp;quot;Scott&amp;quot;&lt;/span&gt;, LastName = &lt;span style="color:#a31515;"&gt;&amp;quot;Seely&amp;quot;&lt;/span&gt;};
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;stream = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MemoryStream&lt;/span&gt;();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;writer = &lt;span style="color:#2b91af;"&gt;XmlDictionaryWriter&lt;/span&gt;.CreateBinaryWriter(stream);
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;ser = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Name&lt;/span&gt;));
  ser.WriteObject(writer, name);
  writer.Flush();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;buffer = &lt;span style="color:blue;"&gt;new byte&lt;/span&gt;[stream.Length];
  &lt;span style="color:#2b91af;"&gt;Array&lt;/span&gt;.Copy(stream.GetBuffer(), buffer, stream.Length);
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;message = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CloudQueueMessage&lt;/span&gt;(buffer);
  cloudQueue.AddMessage(message, &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromHours(1));
}&lt;/pre&gt;
&lt;p&gt;And read from the queue thusly:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main()
{
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;client = &lt;span style="color:#2b91af;"&gt;Utility&lt;/span&gt;.StorageAccount.CreateCloudQueueClient();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;cloudQueue = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CloudQueue&lt;/span&gt;(
    &lt;span style="color:#2b91af;"&gt;Utility&lt;/span&gt;.StorageAccount.QueueEndpoint + &lt;span style="color:#a31515;"&gt;&amp;quot;friseton&amp;quot;&lt;/span&gt;,
    client.Credentials);
  cloudQueue.CreateIfNotExist();
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;ser = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Name&lt;/span&gt;));
  &lt;span style="color:blue;"&gt;var &lt;/span&gt;timeToStop = &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now + &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMinutes(2);
  &lt;span style="color:blue;"&gt;while &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now &amp;lt; timeToStop)
  {
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(cloudQueue.RetrieveApproximateMessageCount() &amp;gt; 0)
    {
      &lt;span style="color:blue;"&gt;var &lt;/span&gt;message = cloudQueue.GetMessage();
      &lt;span style="color:blue;"&gt;var &lt;/span&gt;buffer = message.AsBytes;
      &lt;span style="color:blue;"&gt;var &lt;/span&gt;writer = &lt;span style="color:#2b91af;"&gt;XmlDictionaryReader&lt;/span&gt;.CreateBinaryReader(buffer, 0, 
        buffer.Length, &lt;span style="color:#2b91af;"&gt;XmlDictionaryReaderQuotas&lt;/span&gt;.Max);
      &lt;span style="color:blue;"&gt;var &lt;/span&gt;name = ser.ReadObject(writer) &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Name&lt;/span&gt;;
      &lt;span style="color:blue;"&gt;if &lt;/span&gt;(name != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
      {
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;{0} {1} {2}&amp;quot;&lt;/span&gt;, name.FirstName, 
          name.LastName, message.InsertionTime);
      }
      cloudQueue.DeleteMessage(message);
    }
    &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1));
  }
}&lt;/pre&gt;
&lt;p&gt;And yes, the queue code also works from your local machine. The example above does require you to have the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd179367.aspx"&gt;Azure SDK&lt;/a&gt; installed.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60725" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Speaking at Chippewa Valley .NET Users’ Group Tomorrow</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/06/23/speaking-at-chippewa-valley-net-users-group-tomorrow.aspx" /><id>/blogs/scott_seely/archive/2010/06/23/speaking-at-chippewa-valley-net-users-group-tomorrow.aspx</id><published>2010-06-23T21:18:00Z</published><updated>2010-06-23T21:18:00Z</updated><content type="html">&lt;p&gt;I&amp;rsquo;ll be doing a beginner&amp;#39;s talk on WCF tomorrow night at the Chippewa Valley .NET Users&amp;rsquo; Group. Details are here: &lt;a href="http://cvnug.wi-ineta.org/DesktopDefault.aspx?tabid=73" title="http://cvnug.wi-ineta.org/DesktopDefault.aspx?tabid=73"&gt;http://cvnug.wi-ineta.org/DesktopDefault.aspx?tabid=73&lt;/a&gt;. I&amp;rsquo;m looking forward to meeting some new people!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60721" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Reading a WebResponse into a byte[]</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/06/15/reading-a-webresponse-into-a-byte.aspx" /><id>/blogs/scott_seely/archive/2010/06/15/reading-a-webresponse-into-a-byte.aspx</id><published>2010-06-15T20:04:00Z</published><updated>2010-06-15T20:04:00Z</updated><content type="html">&lt;p&gt;This question came up on Twitter. I&amp;rsquo;m posting the solution here for posterity. How do you read a non-seekable Stream into a byte[]? Specifically, a HttpWebResponse? Like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Program
&lt;/span&gt;{
  &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
  {
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;request = &lt;span style="color:#2b91af;"&gt;WebRequest&lt;/span&gt;.Create(&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.scottseely.com/blog.aspx&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;response = request.GetResponse() &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HttpWebResponse&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;stream = response.GetResponseStream();
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;buffer = &lt;span style="color:blue;"&gt;new byte&lt;/span&gt;[&lt;span style="color:blue;"&gt;int&lt;/span&gt;.Parse(response.Headers[&lt;span style="color:#a31515;"&gt;&amp;quot;Content-Length&amp;quot;&lt;/span&gt;])];
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;bytesRead = 0;
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;totalBytesRead = bytesRead;
    &lt;span style="color:blue;"&gt;while&lt;/span&gt;(totalBytesRead &amp;lt; buffer.Length)
    {
      bytesRead = stream.Read(buffer, bytesRead, buffer.Length - bytesRead);
      totalBytesRead += bytesRead;
    }&lt;/pre&gt;
&lt;pre class="code"&gt;    stream.Close();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#2b91af;"&gt;Encoding&lt;/span&gt;.UTF8.GetString(buffer, 0, totalBytesRead));
  }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60591" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>XmlDictionary and Binary Serialization</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/06/14/xmldictionary-and-binary-serialization.aspx" /><id>/blogs/scott_seely/archive/2010/06/14/xmldictionary-and-binary-serialization.aspx</id><published>2010-06-14T13:00:00Z</published><updated>2010-06-14T13:00:00Z</updated><content type="html">&lt;p&gt;One of the interesting things that came out of WCF is the improvements in Infoset serialization. In particular, WCF introduced a format for binary serialization which reduces space concerns for objects. One of the keys to saving space is the notion of an XmlDictionary. The WCF serialization folks asked the questions: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How much could we reduce the size of a message if we allowed the parties communicating to exchange metadata about the messages? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What if we could reduce the size of messages by exchanging aliases for the XML Infoset node names?&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The result of this &lt;em&gt;what if&lt;/em&gt; experiment is the XmlDictionary and XmlBinaryWriterSession. The mechanism is astonishingly simple. Assume that both ends have a mechanism for exchanging information about what to call the two parts of a QName: name namespace and the name of the node. Instead of sending namespace:element qualified items, send aliases. This works well in WCF messaging and happens whenever you send messages over the binary serializer. You can also use this in your own code that uses a binary serializer. The only requirement is that the serializer and deserializer have to agree on the makeup of the XmlDictionary. Let&amp;rsquo;s start by looking at some code that does plain old binary serialization.&lt;/p&gt;
&lt;p&gt;We start with an object:&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre style="font-family:consolas;"&gt;&amp;nbsp;&amp;nbsp;[&lt;span style="color:#2b91af;"&gt;DataContract&lt;/span&gt;(Namespace&amp;nbsp;=&amp;nbsp;&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.friseton.com/Name/2010/06&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&lt;span style="color:#2b91af;"&gt;DataMember&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;nbsp;FirstName&amp;nbsp;{&amp;nbsp;&lt;span style="color:blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color:blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&lt;span style="color:#2b91af;"&gt;DataMember&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;nbsp;LastName&amp;nbsp;{&amp;nbsp;&lt;span style="color:blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color:blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&lt;span style="color:#2b91af;"&gt;DataMember&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;&amp;nbsp;Birthday&amp;nbsp;{&amp;nbsp;&lt;span style="color:blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color:blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;I then have a &amp;lsquo;driver&amp;rsquo; program:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;span style="color:blue;"&gt;
&lt;pre style="font-family:consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;void&lt;/span&gt;&amp;nbsp;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[]&amp;nbsp;args)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FirstName&amp;nbsp;=&amp;nbsp;&lt;span style="color:#a31515;"&gt;&amp;quot;Scott&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LastName&amp;nbsp;=&amp;nbsp;&lt;span style="color:#a31515;"&gt;&amp;quot;Seely&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Birthday&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(1900,&amp;nbsp;4,&amp;nbsp;5)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;serializer&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;&amp;nbsp;(&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Serialize&amp;nbsp;Binary:&amp;nbsp;{0}&amp;nbsp;bytes&amp;quot;&lt;/span&gt;,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SerializeBinary(person,&amp;nbsp;serializer).Length);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Serialize&amp;nbsp;Binary&amp;nbsp;with&amp;nbsp;Dictionary:&amp;nbsp;{0}&amp;nbsp;bytes&amp;quot;&lt;/span&gt;,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SerializeBinaryWithDictionary(person,&amp;nbsp;serializer).Length);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;The application emits the size of the streams when each object is written out. The first, SerializeBinary, does not use a dictionary. As a result, it won&amp;rsquo;t have access to the aliases and must instead write out the full object. &lt;/p&gt;
&lt;p&gt;
&lt;span style="color:blue;"&gt;
&lt;pre style="font-family:consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;SerializeBinary(&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;&amp;nbsp;person,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;&amp;nbsp;serializer)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;stream&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;MemoryStream&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;writer&amp;nbsp;=&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionaryWriter&lt;/span&gt;.CreateBinaryWriter(stream);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;serializer.WriteObject(writer,&amp;nbsp;person);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writer.Flush();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;return&lt;/span&gt;&amp;nbsp;stream;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;In this case, we get a stream which contains 146 bytes. That&amp;rsquo;s pretty poor considering that we are interested in 10 characters (28 bytes: each string has a 4 byte length and then 2 bytes/character) and a simple DateTime representation (4 bytes). Can we make this smaller? How close can we get to 32 bytes? The answer: really close! &lt;/p&gt;
&lt;p&gt;The version of SerializeBinaryWithDictionary that I wrote is verbose: it contains a number of lines that show what is going on internally. Your own code may be as long, but would include the lines as debug output.Please note that you need to include a reference to the XMLSchema-instance namespace in your dictionary so that both the reader and writer agree on the value of this attribute. &lt;/p&gt;
&lt;p&gt;
&lt;span style="color:blue;"&gt;
&lt;pre style="font-family:consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;SerializeBinaryWithDictionary(&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;&amp;nbsp;person,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;&amp;nbsp;serializer)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;stream&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;MemoryStream&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;dictionary&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionary&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;session&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlBinaryWriterSession&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.TryAdd(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;),&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;FirstName&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.TryAdd(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;),&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;LastName&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.TryAdd(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;Birthday&amp;quot;&lt;/span&gt;),&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;Birthday&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.TryAdd(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;),&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;Person&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.TryAdd(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.friseton.com/Name/2010/06&amp;quot;&lt;/span&gt;),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;xmlns&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.TryAdd(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;xmlns&amp;nbsp;for&amp;nbsp;xsi&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;writer&amp;nbsp;=&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionaryWriter&lt;/span&gt;.CreateBinaryWriter(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stream,&amp;nbsp;dictionary,&amp;nbsp;session);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;serializer.WriteObject(writer,&amp;nbsp;person);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writer.Flush();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;return&lt;/span&gt;&amp;nbsp;stream;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;The size difference is striking: we shave off 108 bytes by using the dictionary. We are getting close to the same size as the memory footprint of the object data! The cool bit: you can use this in your own code. The dictionary needs to be shared between the reader and writer sessions (there is a corresponding XmlBinaryReaderSession which can also be populated from the common dictionary via the deserialization process). For posterity, the output of the program is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;/code&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A slightly different version that shows both reading and writing with a shared understanding of what the dictionary looks like follows:&lt;/p&gt;
&lt;p&gt;
&lt;span style="color:blue;"&gt;
&lt;pre style="font-family:consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;SerializeBinaryWithDictionary(&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;&amp;nbsp;person,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;&amp;nbsp;serializer)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;strings&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;XmlDictionaryString&lt;/span&gt;&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;stream&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;MemoryStream&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;dictionary&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionary&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;session&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlBinaryWriterSession&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;rdr&amp;nbsp;=&amp;nbsp;&lt;span style="color:blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlBinaryReaderSession&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strings.Add(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strings.Add(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strings.Add(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;Birthday&amp;quot;&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strings.Add(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strings.Add(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.friseton.com/Name/2010/06&amp;quot;&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strings.Add(dictionary.Add(&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Added&amp;nbsp;xmlns&amp;nbsp;with&amp;nbsp;key:&amp;nbsp;{0}&amp;quot;&lt;/span&gt;,&amp;nbsp;key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;writer&amp;nbsp;=&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionaryWriter&lt;/span&gt;.CreateBinaryWriter(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stream,&amp;nbsp;dictionary,&amp;nbsp;session);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;val&amp;nbsp;&lt;span style="color:blue;"&gt;in&lt;/span&gt;&amp;nbsp;strings)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;if&lt;/span&gt;&amp;nbsp;(session.TryAdd(val,&amp;nbsp;&lt;span style="color:blue;"&gt;out&lt;/span&gt;&amp;nbsp;key))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rdr.Add(key,&amp;nbsp;val.Value);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;serializer.WriteObject(writer,&amp;nbsp;person);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writer.Flush();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stream.Position&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;reader&amp;nbsp;=&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionaryReader&lt;/span&gt;.CreateBinaryReader(stream,&amp;nbsp;dictionary,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;XmlDictionaryReaderQuotas&lt;/span&gt;.Max,&amp;nbsp;rdr);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;var&lt;/span&gt;&amp;nbsp;per&amp;nbsp;=&amp;nbsp;serializer.ReadObject(reader)&amp;nbsp;&lt;span style="color:blue;"&gt;as&lt;/span&gt;&amp;nbsp;&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writer.Flush();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;return&lt;/span&gt;&amp;nbsp;stream;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Looking at the above, we can also account for the missing 6 bytes in our serialization: the extra 6 bytes are names of the nodes. &lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Serialize Binary: 146 bytes &lt;br /&gt;Added FirstName with key: 0 &lt;br /&gt;Added LastName with key: 1 &lt;br /&gt;Added Birthday with key: 2 &lt;br /&gt;Added Person with key: 3 &lt;br /&gt;Added xmlns with key: 4 &lt;br /&gt;Added xmlns for xsi with key: 5 &lt;br /&gt;Serialize Binary with Dictionary: 38 bytes&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60437" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Speaking at Chicago Architects Group May 18</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/05/17/speaking-at-chicago-architects-group-may-18.aspx" /><id>/blogs/scott_seely/archive/2010/05/17/speaking-at-chicago-architects-group-may-18.aspx</id><published>2010-05-17T23:53:00Z</published><updated>2010-05-17T23:53:00Z</updated><content type="html">&lt;p&gt;I&amp;rsquo;ll be speaking at the Chicago Architects Group on May 18 over at the ITA (next to Union Station in Chicago- corner of Adams and Wacker). My topic is Azure for Architects. In this talk, I go over how to look at and use Azure from a software architecture point of view. Unlike most Azure talks, this one has no code in it&amp;mdash;just concepts. This isn&amp;rsquo;t the type of talk I normally give, but given the crowd, architecture and slides will work better than whiz bang demos. &lt;/p&gt;
&lt;p&gt;The slides are &lt;a href="http://www.scottseely.com/downloads/Azure%20for%20Architects.pptx"&gt;here&lt;/a&gt; if you want them. I tend to use slides as guideposts when I present. Please don&amp;rsquo;t look at these slides as notes. 80% of the presentation is in what I say, not in what you can read. I&amp;rsquo;ll try to record the presentation as well and will put up the recording if the quality is good enough. There are still some seats open. Register at &lt;a href="http://chicagoarchitectsgroup.eventbrite.com"&gt;http://chicagoarchitectsgroup.eventbrite.com&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=58930" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Custom ChannelFactory Creation</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/05/07/custom-channelfactory-creation.aspx" /><id>/blogs/scott_seely/archive/2010/05/07/custom-channelfactory-creation.aspx</id><published>2010-05-07T22:06:00Z</published><updated>2010-05-07T22:06:00Z</updated><content type="html">&lt;p&gt;Just the other day, Derik Whitaker ran into some issues setting up his ChannelFactory to handle large object graphs being returned to his clients (post is &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2010/05/04/setting-maxitemsinobjectgraph-for-wcf-there-has-to-be-a-better-way.aspx"&gt;here&lt;/a&gt;). After some back and forth through email, we came up with a solution. Instead of use the default ChannelFactory&amp;lt;T&amp;gt;, we created a new class that inherits from ChannelFactory&amp;lt;T&amp;gt; and sets the DataContractSerializerBehavior to handle int.MaxValue objects in the graph.&lt;/p&gt;
&lt;p&gt;The trick is to override the ChannelFactory&amp;lt;T&amp;gt;.OnOpening method. This method is called as the ChannelFactory is opened and allows a derived class to alter the behavior at the last minute. All OperationDescriptions have a DataContractSerializerOperationBehavior attached to them. What we want to do is pull out that behavior and set the MaxItemsInObjectGraph property to int.MaxValue so that it allows all content to be serialized in. Derik&amp;rsquo;s use case was valid&amp;mdash;he owned the client and server and wanted to incur any penalty associated with reading ALL data. If you are in a similar situation and need to remove that safety net/throttle in your code, here is what you need. Note that the constructors aren&amp;rsquo;t interesting other than they preserve the signatures made available through ChannelFactory&amp;lt;T&amp;gt; and make them visible in my DerikChannelFactory&amp;lt;T&amp;gt;. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DerikChannelFactory&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;ChannelFactory&lt;/span&gt;&amp;lt;T&amp;gt;
{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DerikChannelFactory(&lt;span style="color:#2b91af;"&gt;Binding &lt;/span&gt;binding) : 
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;(binding) { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DerikChannelFactory(&lt;span style="color:#2b91af;"&gt;ServiceEndpoint &lt;/span&gt;endpoint) : 
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;(endpoint) { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DerikChannelFactory(&lt;span style="color:blue;"&gt;string &lt;/span&gt;endpointConfigurationName) : 
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;(endpointConfigurationName) { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DerikChannelFactory(&lt;span style="color:#2b91af;"&gt;Binding &lt;/span&gt;binding, &lt;span style="color:#2b91af;"&gt;EndpointAddress &lt;/span&gt;remoteAddress) : 
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;(binding, remoteAddress) { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DerikChannelFactory(&lt;span style="color:#2b91af;"&gt;Binding &lt;/span&gt;binding, &lt;span style="color:blue;"&gt;string &lt;/span&gt;remoteAddress) : 
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;(binding, remoteAddress) { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DerikChannelFactory(&lt;span style="color:blue;"&gt;string &lt;/span&gt;endpointConfigurationName, 
        &lt;span style="color:#2b91af;"&gt;EndpointAddress &lt;/span&gt;remoteAddress) : 
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;(endpointConfigurationName, remoteAddress) { }

    &lt;span style="color:blue;"&gt;protected override void &lt;/span&gt;OnOpening()
    {
        &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;operation &lt;span style="color:blue;"&gt;in &lt;/span&gt;Endpoint.Contract.Operations)
        {
            &lt;span style="color:blue;"&gt;var &lt;/span&gt;behavior = 
                operation.Behaviors.
                    Find&amp;lt;&lt;span style="color:#2b91af;"&gt;DataContractSerializerOperationBehavior&lt;/span&gt;&amp;gt;();
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(behavior != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            {
                behavior.MaxItemsInObjectGraph = &lt;span style="color:blue;"&gt;int&lt;/span&gt;.MaxValue;
            }
        }
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;.OnOpening();
    }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The OnOpening override is also a good place to inject behaviors or other items if you want to make sure that all ChannelFactory instances have the same setup without resorting to configuration or code for each instance.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=58471" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>Move to WCF 4.0 for Less Configuration/Code</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/05/04/move-to-wcf-4-0-for-less-configuration-code.aspx" /><id>/blogs/scott_seely/archive/2010/05/04/move-to-wcf-4-0-for-less-configuration-code.aspx</id><published>2010-05-04T05:00:00Z</published><updated>2010-05-04T05:00:00Z</updated><content type="html">&lt;p&gt;People have lots of complaints around WCF. For the 3.x codebase, many don&amp;rsquo;t like the amount of configuration one has to write or code in order to get a service up and running. For example, let&amp;rsquo;s assume that we have a simple service contract, IEchoService. &lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;(Namespace=&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.friseton.com/Echo&amp;quot;&lt;/span&gt;)]
&lt;span style="color:blue;"&gt;interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEchoService
&lt;/span&gt;{
  [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;]
  &lt;span style="color:blue;"&gt;string &lt;/span&gt;Echo(&lt;span style="color:blue;"&gt;string &lt;/span&gt;value);
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;The class is implemented by EchoService:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EchoService &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IEchoService
&lt;/span&gt;{
  &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Echo(&lt;span style="color:blue;"&gt;string &lt;/span&gt;value)
  {
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
  }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In .NET 3.x, we would then have to setup some endpoints, each endpoint specific to the protocol we wanted to understand. We had to remember things like &amp;ldquo;URLs that begin with net.tcp use the NetTcpBinding.&amp;rdquo; For intranet and local machine communication, this is a pain in the butt. In .NET 4.0, the common case of taking the defaults is much easier. If you plan on listening at the base URL(s) for the service, a console application can look like this:&lt;/p&gt;
&lt;p&gt;(code only)&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;netTcp = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;net.tcp://{0}/EchoService&amp;quot;&lt;/span&gt;, 
  &lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.MachineName));
&lt;span style="color:blue;"&gt;var &lt;/span&gt;netPipe = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;net.pipe://{0}/EchoService&amp;quot;&lt;/span&gt;, 
  &lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.MachineName));
&lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;host = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceHost&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;EchoService&lt;/span&gt;), netTcp, netPipe))
{
  host.Open();
  &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Press [Enter] to exit.&amp;quot;&lt;/span&gt;);
  &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You could also configure the base URIs if you wanted this all to be dynamic. This mechanism only works if you don&amp;rsquo;t explicitly add any endpoints. Choosing to add any endpoint: discovery, metadata, or a specific contract WILL mean you have to specify everything. The implicit behavior will expose all contracts on the endpoint, so a service that implements 2 or more contracts will listen for all contracts when you use implicit listeners.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=58117" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>More with Discovery, Day 4</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/05/03/more-with-discovery-day-4.aspx" /><id>/blogs/scott_seely/archive/2010/05/03/more-with-discovery-day-4.aspx</id><published>2010-05-03T05:00:00Z</published><updated>2010-05-03T05:00:00Z</updated><content type="html">&lt;p&gt;Previously, we looked at configuring discovery on the server. What about the client? To discover from the client, we use a class named DiscoveryClient. DiscoveryClient implements the WS-Discovery protocol. Discovery is typically done over UDP because UDP allows for endpoints to broadcast a message. &lt;/p&gt;
&lt;p&gt;The client uses a FindCriteria instance. In our case, we will ask for discovery to give us the metadata exchange endpoints that have definitions for ITest. Upon finding 1 of these, or timing out, we will resolve the metadata exchange endpoint and ask for information about the endpoint. If at least one of those is found (which it should be but it may disappear in between the first request and this one), extract the ITest information and create an ITest ChannelFactory using the discovered binding and endpoint. Sample code looks exactly like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:green;"&gt;// Create a client to find ITest instance. Return as soon as 
// 1 is found.
&lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;discoveryClient = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DiscoveryClient&lt;/span&gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;UdpDiscoveryEndpoint&lt;/span&gt;());
&lt;span style="color:blue;"&gt;var &lt;/span&gt;criteria = &lt;span style="color:#2b91af;"&gt;FindCriteria&lt;/span&gt;.
  CreateMetadataExchangeEndpointCriteria(&lt;span style="color:blue;"&gt;typeof &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ITest&lt;/span&gt;));
criteria.MaxResults = 1;
&lt;span style="color:blue;"&gt;var &lt;/span&gt;findResponse = discoveryClient.Find(criteria);
discoveryClient.Close();
&lt;span style="color:blue;"&gt;if &lt;/span&gt;(findResponse.Endpoints.Count &amp;gt; 0)
{
  &lt;span style="color:green;"&gt;// Resolve the metadata for the first address. 
  // Return the binding and address information.
  &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;endpoints = &lt;span style="color:#2b91af;"&gt;MetadataResolver&lt;/span&gt;.Resolve(&lt;span style="color:blue;"&gt;typeof &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ITest&lt;/span&gt;), 
    findResponse.Endpoints[0].Address);
  &lt;span style="color:blue;"&gt;if &lt;/span&gt;(endpoints.Count &amp;gt; 0)
  {
    &lt;span style="color:green;"&gt;// Create a factory based on the binding and address information
    // we received from the metadata endpoint.
    &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;factory = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ChannelFactory&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;ITest&lt;/span&gt;&amp;gt;(endpoints[0].Binding, 
      endpoints[0].Address);
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;channel = factory.CreateChannel();

    &lt;span style="color:green;"&gt;// Call the add function
    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(channel.Add(3, 4));
    factory.Close();
  }
}&lt;/pre&gt;
&lt;p&gt;The above code will fail if authentication credentials other than Windows or anonymous are required. But, if you use standard windows authentication on the service (or nothing) this works well. Discovery is well suited to intranet scenarios, because things like Windows identities and authentication are already in use.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=57878" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry><entry><title>More with Discovery, Day 3</title><link rel="alternate" type="text/html" href="/blogs/scott_seely/archive/2010/04/30/more-with-discovery-day-3.aspx" /><id>/blogs/scott_seely/archive/2010/04/30/more-with-discovery-day-3.aspx</id><published>2010-04-30T05:00:00Z</published><updated>2010-04-30T05:00:00Z</updated><content type="html">&lt;p&gt;By now, you might be wondering where a person would actually use discovery. A common case would be allowing two processes on the same machine to find each other and allow for dynamic naming of all endpoints (such as using GUIDs in the URLs). This could be used by every Windows Service that has an application running in the system tray. In the enterprise, you would use discovery as one part of a publish and subscribe system. The subscribers would query for all endpoints that publish some kind of information (which would allow the subscribers to poll). Alternatively, a publisher could periodically ask for all entities on the network that were interested in a given topic and push to those endpoints. Likewise, a client could look for a service that implemented some other functionality and dynamically configure itself (instead of needing a priori knowledge about how infrastructure is deployed). &lt;/p&gt;
&lt;p&gt;To make a service discoverable on the server, you add a ServiceDiscoveryBehavior to the service. This behavior, when combined with a UdpDiscoveryEndpoint, allows the service to be found over a broadcast message sent on the network. If you want clients to be able to automatically configure themselves, you need to add an IMetadataExchange endpoint as well. The IMetadataExchange endpoint allows the service to send information about the contracts in use, the bindings against those contracts, and address information on where the service is listening for messages.&lt;/p&gt;
&lt;p&gt;The following code constructs a ServiceHost for some service, TestService, that implements a contract named ITest. &lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;baseUri = &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;net.tcp://{0}/Test&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.MachineName);
&lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;host = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceHost&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TestService&lt;/span&gt;), &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(baseUri)))
{
  &lt;span style="color:green;"&gt;// Make the service discoverable and make sure it has an
  // endpoint to announce its presence.
  &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;discoveryBehavior = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceDiscoveryBehavior&lt;/span&gt;();
  discoveryBehavior.AnnouncementEndpoints.Add(
    &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;UdpAnnouncementEndpoint&lt;/span&gt;());
  host.Description.Behaviors.Add(discoveryBehavior);

  &lt;span style="color:green;"&gt;// Make sure the service can respond to probes.
  &lt;/span&gt;host.AddServiceEndpoint(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;UdpDiscoveryEndpoint&lt;/span&gt;());

  &lt;span style="color:green;"&gt;// Add the ability to handle Metadata requests (aka WSDL)
  &lt;/span&gt;host.Description.Behaviors.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceMetadataBehavior&lt;/span&gt;());
  host.AddServiceEndpoint(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IMetadataExchange&lt;/span&gt;), 
    &lt;span style="color:#2b91af;"&gt;MetadataExchangeBindings&lt;/span&gt;.CreateMexTcpBinding(), &lt;span style="color:#a31515;"&gt;&amp;quot;/mex&amp;quot;&lt;/span&gt;);

  &lt;span style="color:green;"&gt;// Tell the service to listen for ITest messages on net.tcp
  &lt;/span&gt;host.AddServiceEndpoint(&lt;span style="color:blue;"&gt;typeof &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ITest&lt;/span&gt;), &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NetTcpBinding&lt;/span&gt;(), 
    &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty);

  &lt;span style="color:green;"&gt;// Open the host and start listening.
  &lt;/span&gt;host.Open();

  &lt;span style="color:green;"&gt;// Display what we are listening for
  &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;endpoint &lt;span style="color:blue;"&gt;in &lt;/span&gt;host.Description.Endpoints)
  {
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;{0}: {1}&amp;quot;&lt;/span&gt;, 
      endpoint.Contract.Name,
      endpoint.ListenUri);
  }

  &lt;span style="color:green;"&gt;// Wait until we are done.
  &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Press [Enter] to exit&amp;quot;&lt;/span&gt;);
  &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;With this code, we have a service that is discoverable and callable without requiring a client to have any code or configuration that is specific to our service (though it may if the developer chooses). &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=57874" width="1" height="1"&gt;</content><author><name>sseely</name><uri>http://devlicio.us/members/sseely/default.aspx</uri></author></entry></feed>
