<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4978326367697120061</id><updated>2012-02-17T04:15:19.198+01:00</updated><category term='linux'/><category term='Obfuscation'/><category term='Encryption'/><category term='bloat'/><category term='WCF'/><category term='osx'/><category term='xp'/><category term='Google Apps'/><category term='minimalism'/><category term='mac'/><category term='Serialization'/><category term='Service Bus'/><title type='text'>The Minimalist Coder</title><subtitle type='html'>"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away" - Antoine de Saint Exupéry</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4978326367697120061.post-5705342069253426976</id><published>2011-06-29T19:43:00.024+02:00</published><updated>2011-10-19T05:14:41.584+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Apps'/><title type='text'>Google Contacts Synchronisation</title><content type='html'>Having recently migrated to Google Apps at the organisation in which I work, one of the glaring omissions we discovered was the concept of a &lt;i&gt;Global Address List&lt;/i&gt; to which I'd personally become accustomed in MS Exchange.  Despite this persistently being at the top of the feature request list with Google, there still seems to be no easy way of sharing contacts between users, and so I decided to write some code to implement it programmatically.&lt;br /&gt;&lt;br /&gt;The application simply copies all contacts from one account (which might be designated the "master") to another, flagging them as it does so in order that they can be deleted/updated when the program is scheduled to run regularly.  As such, the destination account's existing contacts are never modified.  This works within Google Apps, and also as a means of syncing contacts between regular Gmail accounts.&lt;br /&gt;&lt;br /&gt;To obtain the reference assemblies, you'll need to get the GData .NET Client Library from &lt;a href="http://code.google.com/p/google-gdata/"&gt;http://code.google.com/p/google-gdata/&lt;/a&gt;, or I've included the relevant DLLs in the source download at &lt;a href="http://www.cslacey.co.uk/blog/downloads/CSL.GoogleContactsSync.zip"&gt;www.cslacey.co.uk/blog/downloads/CSL.GoogleContactsSync.zip&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The latter link also contains the compiled application - to start using it straight away, simply enter the relevant credentials into the .config file within /bin/Release, and run CSL.GoogleContactsSync.ConsoleApp.exe.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;(Assembly references: System.Configuration, Google.GData.Client, Google.GData.Contacts, Google.GData.Extensions)&lt;/i&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Configuration;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Google.Contacts;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Google.GData.Client;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Google.GData.Contacts;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; CSL.GoogleContactsSync.ConsoleApp&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;br /&gt;   {&lt;br /&gt;      &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; MAX_BATCH_SIZE = 100;&lt;br /&gt;      &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GOOGLE_APP_NAME = &lt;span class="str"&gt;"CSL.GoogleContactsSync.ConsoleApp"&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GAL_FIELD_KEY = &lt;span class="str"&gt;"Origin"&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GAL_FIELD_VALUE = &lt;span class="str"&gt;"Global Address List"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;      {&lt;br /&gt;         List&amp;lt;Contact&amp;gt; sourceContacts = GetSourceContacts(&lt;br /&gt;             ConfigurationManager.AppSettings[&lt;span class="str"&gt;"SourceGoogleUsername"&lt;/span&gt;],&lt;br /&gt;             ConfigurationManager.AppSettings[&lt;span class="str"&gt;"SourceGooglePassword"&lt;/span&gt;]);&lt;br /&gt;         DeleteExistingGlobalContacts(&lt;br /&gt;             ConfigurationManager.AppSettings[&lt;span class="str"&gt;"DestinationGoogleUsername"&lt;/span&gt;],&lt;br /&gt;             ConfigurationManager.AppSettings[&lt;span class="str"&gt;"DestinationGooglePassword"&lt;/span&gt;]);&lt;br /&gt;         InsertContacts(sourceContacts,&lt;br /&gt;             ConfigurationManager.AppSettings[&lt;span class="str"&gt;"DestinationGoogleUsername"&lt;/span&gt;],&lt;br /&gt;             ConfigurationManager.AppSettings[&lt;span class="str"&gt;"DestinationGooglePassword"&lt;/span&gt;]);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// Retrieve all contacts from the specified account in a form&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// suitable for insertion into other destination accounts&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; List&amp;lt;Contact&amp;gt; GetSourceContacts(&lt;br /&gt;          &lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; password)&lt;br /&gt;      {&lt;br /&gt;         List&amp;lt;Contact&amp;gt; result = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Contact&amp;gt;();&lt;br /&gt;&lt;br /&gt;         RequestSettings requestSettings = &lt;span class="kwrd"&gt;new&lt;/span&gt; RequestSettings(&lt;br /&gt;             GOOGLE_APP_NAME, username, password);&lt;br /&gt;         ContactsRequest contactsRequest =&lt;br /&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; ContactsRequest(requestSettings);&lt;br /&gt;         Feed&amp;lt;Contact&amp;gt; feed = contactsRequest.GetContacts();&lt;br /&gt;         feed.AutoPaging = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Contact contact &lt;span class="kwrd"&gt;in&lt;/span&gt; feed.Entries)&lt;br /&gt;         {&lt;br /&gt;            &lt;span class="rem"&gt;// Remove all group membership, as groups may not exist in&lt;/span&gt;&lt;br /&gt;            &lt;span class="rem"&gt;// destination account&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;while&lt;/span&gt; (contact.GroupMembership.Count &amp;gt; 0)&lt;br /&gt;            {&lt;br /&gt;               contact.GroupMembership.RemoveAt(0);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class="rem"&gt;// Remove all user defined fields, as they may not exist in&lt;/span&gt;&lt;br /&gt;            &lt;span class="rem"&gt;// destination account&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;while&lt;/span&gt; (contact.ContactEntry.UserDefinedFields.Count &amp;gt; 0)&lt;br /&gt;            {&lt;br /&gt;               contact.ContactEntry.UserDefinedFields.RemoveAt(0);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class="rem"&gt;// Flag retrieved contact as originating from the GAL&lt;/span&gt;&lt;br /&gt;            contact.ContactEntry.UserDefinedFields.Add(&lt;br /&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; UserDefinedField(GAL_FIELD_VALUE, GAL_FIELD_KEY));&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(String.Format(&lt;span class="str"&gt;"RETRIEVING CONTACT: {0}"&lt;/span&gt;,&lt;br /&gt;                contact.Name.FullName));&lt;br /&gt;            result.Add(contact);&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// Delete all contacts which have been flagged&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// as originating from the GAL&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DeleteExistingGlobalContacts(&lt;br /&gt;          &lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; password)&lt;br /&gt;      {&lt;br /&gt;         RequestSettings requestSettings = &lt;span class="kwrd"&gt;new&lt;/span&gt; RequestSettings(&lt;br /&gt;             GOOGLE_APP_NAME, username, password);&lt;br /&gt;         ContactsRequest contactsRequest =&lt;br /&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; ContactsRequest(requestSettings);&lt;br /&gt;         Feed&amp;lt;Contact&amp;gt; feed = contactsRequest.GetContacts();&lt;br /&gt;         feed.AutoPaging = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;         List&amp;lt;Contact&amp;gt; contactsToDelete;&lt;br /&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;         {&lt;br /&gt;            contactsToDelete = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Contact&amp;gt;();&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Contact contact &lt;span class="kwrd"&gt;in&lt;/span&gt; feed.Entries)&lt;br /&gt;            {&lt;br /&gt;               &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0;&lt;br /&gt;                   i &amp;lt; contact.ContactEntry.UserDefinedFields.Count; i++)&lt;br /&gt;               {&lt;br /&gt;                  &lt;span class="kwrd"&gt;if&lt;/span&gt; (contact.ContactEntry.UserDefinedFields[i].Key&lt;br /&gt;                      == GAL_FIELD_KEY&lt;br /&gt;                      &amp;amp;&amp;amp; contact.ContactEntry.UserDefinedFields[i].Value&lt;br /&gt;                      == GAL_FIELD_VALUE)&lt;br /&gt;                  {&lt;br /&gt;                     &lt;span class="rem"&gt;// Contact originated from GAL, so add it to the&lt;/span&gt;&lt;br /&gt;                     &lt;span class="rem"&gt;// delete batch&lt;/span&gt;&lt;br /&gt;                     Console.WriteLine(String.Format(&lt;span class="str"&gt;"PENDING DELETE: {0}"&lt;/span&gt;,&lt;br /&gt;                         contact.Name.FullName));&lt;br /&gt;                     contactsToDelete.Add(contact);&lt;br /&gt;                  }&lt;br /&gt;               }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(&lt;span class="str"&gt;"BATCH DELETING {0} Contacts"&lt;/span&gt;,&lt;br /&gt;                contactsToDelete.Count);&lt;br /&gt;            contactsRequest.Batch(contactsToDelete, feed,&lt;br /&gt;                GDataBatchOperationType.delete);&lt;br /&gt;&lt;br /&gt;            &lt;span class="rem"&gt;// Re-intialise batch and feed for next execution&lt;/span&gt;&lt;br /&gt;            contactsToDelete = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Contact&amp;gt;();&lt;br /&gt;            feed = contactsRequest.GetContacts();&lt;br /&gt;         }&lt;br /&gt;         &lt;span class="kwrd"&gt;while&lt;/span&gt; (feed.Entries.Count() &amp;gt; 0 &amp;amp;&amp;amp; contactsToDelete.Count &amp;gt; 0);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// Insert the specified contacts&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InsertContacts(&lt;br /&gt;          List&amp;lt;Contact&amp;gt; contacts, &lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; password)&lt;br /&gt;      {&lt;br /&gt;         RequestSettings requestSettings = &lt;span class="kwrd"&gt;new&lt;/span&gt; RequestSettings(&lt;br /&gt;             GOOGLE_APP_NAME, username, password);&lt;br /&gt;         ContactsRequest contactsRequest =&lt;br /&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; ContactsRequest(requestSettings);&lt;br /&gt;         Feed&amp;lt;Contact&amp;gt; feed = contactsRequest.GetContacts();&lt;br /&gt;         List&amp;lt;Contact&amp;gt; contactsToInsert = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Contact&amp;gt;();&lt;br /&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Contact contact &lt;span class="kwrd"&gt;in&lt;/span&gt; contacts)&lt;br /&gt;         {&lt;br /&gt;            Console.WriteLine(String.Format(&lt;span class="str"&gt;"PENDING INSERT: {0}"&lt;/span&gt;,&lt;br /&gt;                contact.Name.FullName));&lt;br /&gt;            contactsToInsert.Add(contact);&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (contactsToInsert.Count == MAX_BATCH_SIZE)&lt;br /&gt;            {&lt;br /&gt;               Console.WriteLine(&lt;span class="str"&gt;"BATCH INSERTING {0} Contacts"&lt;/span&gt;,&lt;br /&gt;                   contactsToInsert.Count);&lt;br /&gt;               contactsRequest.Batch(contactsToInsert, feed,&lt;br /&gt;                   GDataBatchOperationType.insert);&lt;br /&gt;&lt;br /&gt;               &lt;span class="rem"&gt;// Re-initialise batch for next execution&lt;/span&gt;&lt;br /&gt;               contactsToInsert = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Contact&amp;gt;();&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         Console.WriteLine(&lt;span class="str"&gt;"BATCH INSERTING {0} Contacts"&lt;/span&gt;,&lt;br /&gt;             contactsToInsert.Count);&lt;br /&gt;         contactsRequest.Batch(contactsToInsert, feed,&lt;br /&gt;             GDataBatchOperationType.insert);&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4978326367697120061-5705342069253426976?l=minimalistcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/5705342069253426976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minimalistcoder.blogspot.com/2011/06/having-recently-migrated-to-google-apps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/5705342069253426976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/5705342069253426976'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/2011/06/having-recently-migrated-to-google-apps.html' title='Google Contacts Synchronisation'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4978326367697120061.post-5611830990944821540</id><published>2009-11-02T10:23:00.020+01:00</published><updated>2009-11-02T12:35:40.467+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><category scheme='http://www.blogger.com/atom/ns#' term='Service Bus'/><title type='text'>Migrating Classic WCF to the Service Bus</title><content type='html'>The Service Bus (within Microsoft's new .NET Services product) is a nice bit of technology that allows two-way communication between nodes on the Internet, regardless of the presence of firewalls, NAT gateways or other complicated network topologies.  It makes possible all sorts of useful tools, such as Rich's and Rob's &lt;a href="http://socketshifter.codeplex.com/"&gt;SocketShifter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What's really nice about Service Bus's implementation, however, (and often overlooked) is that it's nothing more than a new set of WCF bindings which result in the creation of publicly reachable and discoverable endpoints.&lt;br /&gt;&lt;br /&gt;With that in mind, I wondered whether I could take my &lt;a href="http://minimalistcoder.blogspot.com/2009/01/self-hosting-wcf.html"&gt;previous simple WCF example&lt;/a&gt;, and change it to use the Service Bus by doing nothing more than modifying the config.  In theory, it seems that this should be possible once the Service Bus becomes a standard part of the .NET framework - but for now it proves difficult. This is because installing the .NET Services CTP will modify your machine.config file such that netTcpRelayBinding cannot be added again as an extension within an app.config, but HAS to be added in that way for machines without the CTP installed (i.e. all of your customers' servers, or indeed an Azure VM).&lt;br /&gt;&lt;br /&gt;The only sensible way to achieve this, therefore, is by explicitly setting options within the code itself - but this proved pretty easy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Messaging Model&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Let's start by modifying the code of the previous example slightly so that we emphasise the delivery of a message and a reply.  We'll make the &lt;em&gt;GetTimestamp&lt;/em&gt; method take a string, which gets printed at the server and copied back within the reply:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;SharedTypes.IHealthCheck&lt;/em&gt;&lt;br /&gt;...&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;[&lt;span style="color: #2b91af;"&gt;OperationContract&lt;/span&gt;]&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; GetTimestamp(&lt;span style="color: blue;"&gt;string&lt;/span&gt; serviceName);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;em&gt;Server.HealthCheck&lt;/em&gt;&lt;br /&gt;...&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; GetTimestamp(&lt;span style="color: blue;"&gt;string&lt;/span&gt; serviceName)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&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;Request received from {0}&amp;quot;&lt;/span&gt;, serviceName);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;&amp;quot;{0}: {1}&amp;quot;&lt;/span&gt;, serviceName, &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Now.ToString());&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;em&gt;Client.Program&lt;/em&gt;&lt;br /&gt;...&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt; (&lt;span style="color: blue;"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;.WriteLine(healthCheck.GetTimestamp(&lt;span style="color: #a31515;"&gt;&amp;quot;My service&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Migrating to Service Bus&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In both the Server and the Client, we now need to configure the endpoint as follows (If you don't yet have a .NET Services account, you can create one at &lt;a href="http://www.microsoft.com/windowsazure/developers/dotnetservices/"&gt;http://www.microsoft.com/windowsazure/developers/dotnetservices/&lt;/a&gt;):&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Specify a Service Bus address (sb://yourAccount.servicebus.windows.net/...)&lt;br /&gt;&lt;li&gt;Specify an appropriate Service Bus binding (here, we'll use NetTcpRelayBinding)&lt;br /&gt;&lt;li&gt;Specify a new behaviour which contains your Service Bus credentials&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;As mentioned before, the only safe way of doing this at the moment is programatically:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Server.Program&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Configure the endpoint of the ServiceHost, just before opening it:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;(Assembly reference: Microsoft.ServiceBus)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel.Description;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; Microsoft.ServiceBus;&lt;/pre&gt;&lt;/div&gt;...&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Construct EndpointBehaviour for SB username and password&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;TransportClientEndpointBehavior&lt;/span&gt; serviceBusCredential =&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TransportClientEndpointBehavior&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceBusCredential.CredentialType =&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;TransportClientCredentialType&lt;/span&gt;.UserNamePassword;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceBusCredential.Credentials.UserName.UserName = &lt;span style="color: #a31515;"&gt;&amp;quot;yourAccount&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceBusCredential.Credentials.UserName.Password = &lt;span style="color: #a31515;"&gt;&amp;quot;yourPassword&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;ServiceHost&lt;/span&gt; serviceHost = &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;HealthCheck&lt;/span&gt;));&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Set the binding manually (overriding the app.config)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;ServiceEndpoint&lt;/span&gt; serviceEndpoint = serviceHost.Description.Endpoints[0];&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceEndpoint.Address = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EndpointAddress&lt;/span&gt;(&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;&amp;quot;sb://yourAccount.servicebus.windows.net/test/&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceEndpoint.Binding = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;NetTcpRelayBinding&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceEndpoint.Behaviors.Add(serviceBusCredential);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceHost.Open();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Keep the process running (hence the service open) for an hour&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Threading.&lt;span style="color: #2b91af;"&gt;Thread&lt;/span&gt;.Sleep(3600000);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Client.HealthCheck&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Configure the endpoint of the ClientBase class we're inheriting from on construction, to ensure we only do it once:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;(Assembly reference: Microsoft.ServiceBus)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; Microsoft.ServiceBus;&lt;/pre&gt;&lt;/div&gt;...&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; HealthCheck()&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Construct EndpointBehaviour for SB username and password&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;TransportClientEndpointBehavior&lt;/span&gt; serviceBusCredential =&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TransportClientEndpointBehavior&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceBusCredential.CredentialType =&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;TransportClientCredentialType&lt;/span&gt;.UserNamePassword;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceBusCredential.Credentials.UserName.UserName = &lt;span style="color: #a31515;"&gt;&amp;quot;yourAccount&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; serviceBusCredential.Credentials.UserName.Password = &lt;span style="color: #a31515;"&gt;&amp;quot;yourPassword&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Set the binding manually (overriding the app.config)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Endpoint.Address = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EndpointAddress&lt;/span&gt;(&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;&amp;quot;sb://yourAccount.servicebus.windows.net/test/&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Endpoint.Binding = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;NetTcpRelayBinding&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Endpoint.Behaviors.Add(serviceBusCredential);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That's it!  If you fire up the server and the client, you should now see them working exactly as before - except you can now have the server running on your home machine behind a NAT gateway, and the client running on your office machine behind a corporate firewall!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4978326367697120061-5611830990944821540?l=minimalistcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/5611830990944821540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minimalistcoder.blogspot.com/2009/11/service-bus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/5611830990944821540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/5611830990944821540'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/2009/11/service-bus.html' title='Migrating Classic WCF to the Service Bus'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4978326367697120061.post-6481375944987032798</id><published>2009-06-29T17:52:00.019+02:00</published><updated>2009-10-18T22:41:19.928+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Triple Boot MacBook</title><content type='html'>Having bought a shiny new MacBook a few months ago, I got a little bored of OS X and wanted to make most use of its Intel chipset - to let me boot into Windows, OS X and Linux all on the same box.&lt;br /&gt;&lt;br /&gt;There are quite a few long-winded, complicated explanations out there that describe how to achieve this, but actually it's quite simple once you know what to avoid. The following procedure has been tested using OS X Leopard (I'm assuming it's already installed), Windows XP Professional SP2 and Ubuntu 9.04.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Install the rEFIt Bootloader&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Bootcamp seems to have problems working with more than two parallel OS's. So inside OS X, download and install rEFIt from &lt;a href="http://refit.sourceforge.net" target="_blank"&gt;http://refit.sourceforge.net&lt;/a&gt;, which is an alternative bootloader providing support for the Extensible Firmware Interface that Macs use.&lt;br /&gt;&lt;br /&gt;Reboot after installing to check that you get the new rEFIt bootup screen, and choose to boot into OS X again.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Partition your drive&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You'll need at least three partitions (one for OS X, one for XP, and one for Ubuntu). Ideally, though, you might choose to have an additional swap partition for Linux, and perhaps a shared data partition which you can access from all three OS's. You'll also probably already have your first partition defined as an EFI system partition - it's best not to fiddle with that.&lt;br /&gt;&lt;br /&gt;Limitations to bear in mind are that the Ubuntu GRUB bootloader must be installed on the third partition, and XP on the fourth (due to their dependence on PC BIOS and the MBR, both seemingly have to be within the first four partitions, and XP must be as "low down" as possible). XP also seems to be unable to see any more than the first four partitions (as it doesn't support the GUID partition scheme), so make sure that your shared data is within the first four.&lt;br /&gt;&lt;br /&gt;I found my ideal partition map to be as follows:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;EFI - 200MB (untouched, as from the factory)&lt;br /&gt;&lt;li&gt;OS X - 50GB (the original OS X partition, shrunk but otherwise not modified)&lt;br /&gt;&lt;li&gt;Shared Data (plus GRUB bootloader for Ubuntu) - 20GB&lt;br /&gt;&lt;li&gt;XP - 50GB&lt;br /&gt;&lt;li&gt;Ubuntu - 25GB&lt;br /&gt;&lt;li&gt;Linux Swap - 2.5GB&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;In OS X, enter the command:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;diskutil list&lt;/pre&gt;&lt;br /&gt;...and you should see that your existing disk structure looks something like this:&lt;br /&gt;&lt;pre&gt;/dev/disk0&lt;br /&gt;#: type name size identifier&lt;br /&gt;0: GUID_partition_scheme *149.1 GB disk0&lt;br /&gt;1: EFI 200.0 MB disk0s1&lt;br /&gt;2: Apple_HFS Macintosh HD 148.9 GB disk0s2&lt;/pre&gt;&lt;br /&gt;Given that you want to resize the large partition and make lots of other smaller ones, you should then issue the following command (without linebreaks, and assuming my desired partition map):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diskutil resizeVolume disk0s2 50G&lt;br /&gt;   "HFS+" "Data" 20G&lt;br /&gt;   "MS-DOS FAT32" "Windows" 50G&lt;br /&gt;   "HFS+" "Linux" 25G&lt;br /&gt;   "HFS+" "Linux Swap" 2.5G&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In actual fact, the formats selected here don't matter all that much, because both Windows and Linux will reformat the relevant drives upon installation.  Make sure, however, that for the Data partition you initially pick a format that Windows &lt;strong&gt;can't&lt;/strong&gt; understand - this will ensure that the Windows partition ends up as drive C upon installation!  You can then reformat Data later (as MS-DOS FAT 32, being the only format all three OSs can read and write) using Terminal or Disk Utility in OSX.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3. Install XP&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Insert your XP boot CD, and restart the machine while holding down the Option (alt) key. Choose the option to boot from CD.&lt;br /&gt;&lt;br /&gt;Install Windows as normal, selecting the fourth partition (which should be labelled C:). I also chose to reformat the drive using NTFS, as this provides better performance than FAT32.&lt;br /&gt;&lt;br /&gt;As Windows needs to restart the machine a couple of times during this process, ensure that each time you select the "Windows" option which should appear in the rEFIt menu, to allow the installation to carry on.&lt;br /&gt;&lt;br /&gt;Once this is complete, install the relevant Windows drivers for the Mac hardware using the "Boot Camp" installer for Windows (on the Mac OS X Install DVD).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4. Install Ubuntu&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Insert a bootable Ubuntu CD, and again restart the machine while holding down the Option (alt) key. Choose the option to boot from CD.&lt;br /&gt;&lt;br /&gt;Install Ubuntu as normal, selecting manual configuration of partitions when prompted. On the subsequent screen, you should select /dev/sda5 to be formatted with ext3 (my preference), and mounted as "/". Assuming my partition map, you should also select /dev/sda6 to be formatted as a swap partition.&lt;br /&gt;&lt;br /&gt;Important: On the final screen of the installer, select 'Advanced...' and change the location of the GRUB bootloader to be /dev/sda3. This is important, as otherwise Ubuntu's bootloader will attempt to take over the whole disk, which can have some odd results working alongside rEFIt.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;5. Celebrate&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;That's it!  The only thing that doesn't work for me (bizarrely) is restarting from within Ubuntu... I have to make sure I only ever choose "Shut Down"!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4978326367697120061-6481375944987032798?l=minimalistcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/6481375944987032798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minimalistcoder.blogspot.com/2009/06/triple-boot-macbook.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/6481375944987032798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/6481375944987032798'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/2009/06/triple-boot-macbook.html' title='Triple Boot MacBook'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4978326367697120061.post-4424385086955132263</id><published>2009-01-22T09:22:00.016+01:00</published><updated>2009-07-09T20:13:21.066+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Serialization'/><category scheme='http://www.blogger.com/atom/ns#' term='Encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='Obfuscation'/><title type='text'>Obfuscating QueryString Parameters</title><content type='html'>I need to provide a link to a URL which contains some parameters I'd like to obfuscate. Specifically, within an automatically generated Email, instead of embedding a link /sendMessage.aspx?address=foo@bar.com&amp;amp;expiry=2009-01-22Z13:30 , I'd prefer /sendMessage.aspx?token=s0MEth1ngUnfath0mable!&lt;br /&gt;&lt;br /&gt;Broken down, my requirements for obfuscation are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Serialize&lt;/strong&gt; an object which contains my parameters (address and expiry), so that it can be transmitted to a different server (i.e. the web server)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Encrypt&lt;/strong&gt; the serialized bytes to prevent tampering&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Make Quotable&lt;/strong&gt; the encrypted bytes so that they can be included within a URL querystring (albeit after a suitable UrlEncode)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Key Generation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;My security requirements are pretty basic, as I'm not trying to protect anything desperately important here - rather prevent basic tampering by spotting patterns in the quotable string. Therefore, I'll keep things as simple as possible and take some shortcuts, for example using a basic security algorithm (DES), and embedding the encryption key within my source code.&lt;br /&gt;&lt;br /&gt;Firstly, we'll need to generate a key upon which the encryption and decryption can occur:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Security.Cryptography;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; ObfuscationTesting&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Program&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Generate a suitable key&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DESCryptoServiceProvider&lt;/span&gt; desCryptoServiceProvider =&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DESCryptoServiceProvider&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; desCryptoServiceProvider.GenerateKey();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Represent key as a quotable string&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; base64EncodedKey =&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.ToBase64String(desCryptoServiceProvider.Key);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Save to file&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;File&lt;/span&gt;.WriteAllText(&lt;span style="color: #a31515;"&gt;@&amp;quot;C:\key.txt&amp;quot;&lt;/span&gt;, base64EncodedKey);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Obfuscator Class&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Now, we'll create a static class that takes any serializable object and returns us a string which represents that object (and, naturally, allows us to re-create the original object from such a string):&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters.Binary;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Security.Cryptography;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; ObfuscationTesting&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Obfsucator&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// The key previously generated&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; KEY = &lt;span style="color: #a31515;"&gt;&amp;quot;MXvUAmUobjA=&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Obfuscate(&lt;span style="color: blue;"&gt;object&lt;/span&gt; targetObject)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Binary serialize&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;MemoryStream&lt;/span&gt; memoryStream = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MemoryStream&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;BinaryFormatter&lt;/span&gt; binaryFormatter = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;BinaryFormatter&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; binaryFormatter.Serialize(memoryStream, targetObject);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] serialized = memoryStream.GetBuffer();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Encrypt&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DESCryptoServiceProvider&lt;/span&gt; desCryptoServiceProvider =&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DESCryptoServiceProvider&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; desCryptoServiceProvider.Key = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.FromBase64String(KEY);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; desCryptoServiceProvider.IV = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.FromBase64String(KEY);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] encrypted = desCryptoServiceProvider&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; .CreateEncryptor()&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; .TransformFinalBlock(serialized, 0, serialized.Length);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Render as string&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; quotable = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.ToBase64String(encrypted);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; quotable;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;object&lt;/span&gt; Deobfuscate(&lt;span style="color: blue;"&gt;string&lt;/span&gt; quotable)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Retrieve the bytes from the quotable string&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] encrypted = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.FromBase64String(quotable);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Decrypt&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DESCryptoServiceProvider&lt;/span&gt; desCryptoServiceProvider =&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DESCryptoServiceProvider&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; desCryptoServiceProvider.Key = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.FromBase64String(KEY);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; desCryptoServiceProvider.IV = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.FromBase64String(KEY);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] serialized = desCryptoServiceProvider&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; .CreateDecryptor()&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; .TransformFinalBlock(encrypted, 0, encrypted.Length);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Deserialize&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;MemoryStream&lt;/span&gt; memoryStream = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MemoryStream&lt;/span&gt;(serialized);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;BinaryFormatter&lt;/span&gt; binaryFormatter = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;BinaryFormatter&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;object&lt;/span&gt; deserialized = binaryFormatter.Deserialize(memoryStream);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; deserialized;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;We'll create a class which contains the parameters I'd like to represent, remembering to mark it as serializable:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; ObfuscationTesting&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Serializable&lt;/span&gt;]&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Token&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; EmailAddress { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; Expiry { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;To construct the URL with the obfuscated parameters, all we need to have is:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;(Assembly reference: System.Web)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;...&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Token&lt;/span&gt; token = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Token&lt;/span&gt;()&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; EmailAddress = &lt;span style="color: #a31515;"&gt;&amp;quot;foo@bar.com&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; Expiry = &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Now.AddHours(1)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; url = &lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515;"&gt;@&amp;quot;/sendMessage.aspx?token={0}&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: #2b91af;"&gt;HttpUtility&lt;/span&gt;.UrlEncode(&lt;span style="color: #2b91af;"&gt;Obfsucator&lt;/span&gt;.Obfuscate(token)));&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And, on our web page that receives the URL, we just need to de-obfuscate again:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; tokenString = Request.QueryString[&lt;span style="color: #a31515;"&gt;&amp;quot;token&amp;quot;&lt;/span&gt;];&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Token&lt;/span&gt; token = (&lt;span style="color: #2b91af;"&gt;Token&lt;/span&gt;)&lt;span style="color: #2b91af;"&gt;Obfsucator&lt;/span&gt;.Deobfuscate(tokenString);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&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; (token.Expiry &amp;lt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Now)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: green;"&gt;// Token has expired&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; Response.End();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: blue;"&gt;string&lt;/span&gt; toAddress = token.EmailAddress;&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: green;"&gt;// etc&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4978326367697120061-4424385086955132263?l=minimalistcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/4424385086955132263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minimalistcoder.blogspot.com/2009/01/obfuscating-querystring-parameters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/4424385086955132263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/4424385086955132263'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/2009/01/obfuscating-querystring-parameters.html' title='Obfuscating QueryString Parameters'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4978326367697120061.post-1553603310470759504</id><published>2009-01-14T14:14:00.003+01:00</published><updated>2009-01-14T17:05:02.741+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Self-Hosting WCF</title><content type='html'>I'd like to have two separate processes (both under my control) communicate over WCF. What's the easiest way to achieve this? As an example, I'd like Process 1 (a client) to be able to check the health or presence of Process 2 (the server) by periodically requesting the server's local time.&lt;br /&gt;&lt;br /&gt;To permit communication, we need to define a &lt;em&gt;contract&lt;/em&gt; between the two processes. All I'd like this contract (let's call it &lt;em&gt;HealthCheck&lt;/em&gt;) to define is an operation &lt;em&gt;GetTimestamp&lt;/em&gt;. Given that my two separate processes will be two separate projects in Visual Studio, and that they both need to access this contract, we'll create a third class library called &lt;em&gt;SharedTypes&lt;/em&gt; that will contain nothing but the contract.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SharedTypes (contains the contract)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Assembly references: System.ServiceModel&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;We'll define the contract as an interface, decorated by System.ServiceModel.ServiceContract. The interface's one method signature (&lt;em&gt;GetTimestamp&lt;/em&gt;) should be decorated by System.ServiceModel.OperationContract.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; SharedTypes&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;ServiceContract&lt;/span&gt;]&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;IHealthCheck&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;OperationContract&lt;/span&gt;]&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; GetTimestamp();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Assembly references: SharedTypes, System.ServiceModel&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;The server process, perhaps unsurprisingly, will need to implement this contract interface as follows:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; SharedTypes;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; Server&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;HealthCheck&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IHealthCheck&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; GetTimestamp()&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Now;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The program's main method will simply instantiate and open a ServiceHost to expose the service, and hang around in the background:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; Server&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Program&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;ServiceHost&lt;/span&gt; serviceHost = &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;HealthCheck&lt;/span&gt;));&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; serviceHost.Open();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Keep the process running (hence the service open) for an hour&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; System.Threading.&lt;span style="color: #2b91af;"&gt;Thread&lt;/span&gt;.Sleep(3600000);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Finally, we'll need to specify the address and protocol by which the service can be called. Part of the joy of WCF is allowing this to be configurable by an end-user or sysadmin, so we'll specify a minimal app.config to contain the core settings we require:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515;"&gt;xml&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;version&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;encoding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; ?&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &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;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;services&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;service&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;Server.HealthCheck&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;endpoint&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;address&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;basic&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;binding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;basicHttpBinding&lt;/span&gt;&amp;quot;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&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; &lt;/span&gt;&lt;span style="color: red;"&gt;contract&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;SharedTypes.IHealthCheck&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;host&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;baseAddresses&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&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;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;add&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;baseAddress&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;http://localhost:8080/HealthCheck&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;baseAddresses&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;host&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;service&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;services&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &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;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Assembly references: SharedTypes, System.ServiceModel&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;The client will also need to have a class that implements the service contract, but we'll make it such that calls to its methods actually result in a remote call over WCF:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; SharedTypes;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; Client&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;HealthCheck&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;ClientBase&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;IHealthCheck&lt;/span&gt;&amp;gt;, &lt;span style="color: #2b91af;"&gt;IHealthCheck&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; GetTimestamp()&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;base&lt;/span&gt;.Channel.GetTimestamp();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The program's main method will just sit in a loop calling and echoing the result from &lt;em&gt;GetTimestamp:&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; Client&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Program&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;HealthCheck&lt;/span&gt; healthCheck = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;HealthCheck&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;while&lt;/span&gt; (&lt;span style="color: blue;"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;.WriteLine(healthCheck.GetTimestamp());&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; &lt;span style="color: green;"&gt;// Wait for a second&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&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; System.Threading.&lt;span style="color: #2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Again, we'll need to specify in app.config the location of the server, and the protocol we want to use:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; line-height: 1em;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515;"&gt;xml&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;version&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;encoding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; ?&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &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;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;client&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;endpoint&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;address&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;http://localhost:8080/HealthCheck/basic&lt;/span&gt;&amp;quot;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&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; &lt;/span&gt;&lt;span style="color: red;"&gt;binding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;basicHttpBinding&lt;/span&gt;&amp;quot;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&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; &lt;/span&gt;&lt;span style="color: red;"&gt;contract&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;SharedTypes.IHealthCheck&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;client&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &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;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4978326367697120061-1553603310470759504?l=minimalistcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/1553603310470759504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minimalistcoder.blogspot.com/2009/01/self-hosting-wcf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/1553603310470759504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/1553603310470759504'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/2009/01/self-hosting-wcf.html' title='Self-Hosting WCF'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4978326367697120061.post-8956611543602604226</id><published>2009-01-14T13:47:00.001+01:00</published><updated>2009-01-14T14:13:05.125+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='minimalism'/><category scheme='http://www.blogger.com/atom/ns#' term='bloat'/><title type='text'>Introduction</title><content type='html'>History, or at least working within my company, has shown that the simplest, most basic implementations of code stand the most chance of being correct. As soon as code is littered with endless if-then-else scenarios or numerous configuration options, it becomes increasingly difficult to spot the core logic, and inevitably, the bugs or inconsistencies.&lt;br /&gt;&lt;br /&gt;Working in the Microsoft space, I have become increasingly frustrated with the typical low signal-to-noise ratio of documentation, samples and articles about Microsoft technologies. Exacerbated by the fact that Microsoft developers (or more specifically Visual Studio developers) have become ever-more dependent on code generators, hidden-away partial classes, and bloated configuration files, there is a tendency for code examples to be little more than screenshots showing which buttons should be pushed within Visual Studio, and which of the configuration options should be tweaked in the sea of automatically generated XML.&lt;br /&gt;&lt;br /&gt;The code samples I plan to show in this blog will attempt to represent the simplest implementations of particular technologies. Paring back the unnecessary bloat from Visual Studio's code generators and from the multitude of code samples on the web is often a fairly time-consuming task, and the primary purpose of these posts is to record any outcomes as notes to myself. Nonetheless, I hope they might also prove useful to others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4978326367697120061-8956611543602604226?l=minimalistcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minimalistcoder.blogspot.com/feeds/8956611543602604226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minimalistcoder.blogspot.com/2009/01/introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/8956611543602604226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4978326367697120061/posts/default/8956611543602604226'/><link rel='alternate' type='text/html' href='http://minimalistcoder.blogspot.com/2009/01/introduction.html' title='Introduction'/><author><name>Chris Lacey</name><uri>http://www.blogger.com/profile/10405697803215160094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_F6UBQL7q9BI/SW4C8fjRsuI/AAAAAAAAAFQ/Txeaaz0lJdE/S220/csl.jpg'/></author><thr:total>0</thr:total></entry></feed>
