<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">

<channel>
	<title>iServiceOriented</title>
	
	<link>http://blog.iserviceoriented.com</link>
	<description>Become a WCF Ninja - WCF Tips and Tricks</description>
	<lastBuildDate>Wed, 05 May 2010 00:42:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/iserviceoriented" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="iserviceoriented" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>33.659639</geo:lat><geo:long>-117.739481</geo:long><item>
		<title>Building Custom HTTP Help Pages With WCF</title>
		<link>http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/</link>
		<comments>http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/#comments</comments>
		<pubDate>Wed, 05 May 2010 00:42:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.iserviceoriented.com/?p=64</guid>
		<description><![CDATA[Some times things you think should be simple turn out to take quite a bit of work to figure out how to do with WCF. One of those things is serving up custom HTTP help pages for your service endpoints. WCF ships with a special behavior, the ServiceMetadataBehavior that provides the functionality used by the [...]]]></description>
			<content:encoded><![CDATA[<p>Some times things you think should be simple turn out to take quite a bit of work to figure out how to do with WCF. One of those things is serving up custom HTTP help pages for your service endpoints. WCF ships with a special behavior, the ServiceMetadataBehavior that provides the functionality used by the standard WSDL pages. It&#8217;s pretty easy to serve up custom WSDL by providing a custom metadata provider, but replacing the HTML pages turns out to require a bit of black magic.</p>
<p>The way you extend a lot of WCF is through custom behaviors. This case is no different. We can use a custom behavior to inject an additional channel dispatcher into our service on startup. A channel dispatcher allows us to intercept messages that match a specific filter and forward the message to an implementation class for handling. By injecting a custom channel dispatcher, we can layer additional contracts on top of our WCF service to accept messages that aren&#8217;t defined by the service contract that is configured for the service host. In this case, we want to intercept raw HTTP GET requests (since SOAP requests will be POST requests) and return an HTML page instead of forwarding the message to the hosted service.</p>
<p>In theory, this should be pretty straightforward, but a few flaws in the design of WCF make this a bit harder than it should be:</p>
<ol>
<li>A channel dispatcher requires a channel listener in order to accept messages. A channel listener can be constructed from a binding, but unfortunately, the http transport part of the binding doesn&#8217;t let you set up a listener for GET requests and a listener for POST requests at the same URL. It&#8217;s possible to configure this, and that is how the built in behavior works, but unfortunately, the WCF team decided to make the required property internal. The only way to get the appropriate behavior is via reflection. It&#8217;s not pretty, but it works.</li>
<li>A channel dispatcher also requires an instance context provider. The instance context provider determines the instancing behavior of a class that receives dispatched messages. WCF ships with multiple instance context modes in the box. Unforunately, all the providers and factories for those providers are also internal. You could theoretically create your own instance context provider, but if you want to create one that works just like the ones that WCF uses, you&#8217;ll need access to even more internal methods. So, the best solution seems to be once again to use reflection to call into some internals and create one of the standard instance context providers.</li>
<li>Because WCF makes sending raw HTTP messages rather cumbersome, we&#8217;ll create a custom message class to abstract the messy details.</li>
</ol>
<p>Now, for the code. Here&#8217;s everything you need to serve custom HTTP help pages along with your service:</p>
<pre class="csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Reflection;

namespace CustomHelpPageBehavior
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(EchoService));
            host.AddServiceEndpoint(typeof(IEchoService), new BasicHttpBinding(), "http://localhost:8080/sample");
            host.Description.Behaviors.Add(new HelpPageBehavior() { Address = new EndpointAddress("http://localhost:8080/sample"), Content = "<html><body>hello world!</body></html>" });

            host.Open();

            Console.WriteLine("Press enter to exit...");
            Console.ReadLine();

            host.Close();

        }
    }

    [ServiceContract]
    public interface IEchoService
    {
        [OperationContract]
        string Echo(string text);
    }

    public class EchoService : IEchoService
    {
        public string Echo(string text)
        {
            return text;
        }
    }

    public class HelpPageBehavior : IServiceBehavior
    {
        public HelpPageBehavior()
        {
            HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
            httpTransport.GetType().GetProperty("Method", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.SetProperty).SetValue(httpTransport, "GET", null);
            Binding = new CustomBinding(new WebMessageEncodingBindingElement() { MessageVersion = MessageVersion.None, ContentTypeMapper = new RawContentTypeMapper() }, httpTransport);
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {

        }

        public Binding Binding
        {
            get;
            set;
        }

        public EndpointAddress Address
        {
            get;
            set;
        }

        class HttpGetContractFilter : MessageFilter
        {
            public override bool Match(Message message)
            {
                HttpRequestMessageProperty prop = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
                if (prop != null)
                {
                    return prop.Method == "GET";
                }
                return false;
            }

            public override bool Match(MessageBuffer buffer)
            {
                using (Message message = buffer.CreateMessage())
                {
                    HttpRequestMessageProperty prop = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
                    if (prop != null)
                    {
                        return prop.Method == "GET";
                    }
                    return false;
                }
            }
        }

        [ServiceContract]
        public interface IHtmlHelp
        {
            [OperationContract(Action = "*", ReplyAction = "*")]
            Message Get(Message message);
        }

        public class HtmlHelp : IHtmlHelp
        {
            public Message Get(Message message)
            {
                return new TextMessage(Content);
            }

            public string Content
            {
                get;
                set;
            }
        }

        public class OperationInvoker : IOperationInvoker
        {
            public OperationInvoker()
            {

            }

            public object[]  AllocateInputs()
            {
             	return new object[1];
            }

            public object  Invoke(object instance, object[] inputs, out object[] outputs)
            {
                outputs = new object[1];
             	outputs[0] = ((IHtmlHelp)instance).Get((Message)inputs[0]);
                return outputs[0];
            }

            public IAsyncResult  InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
            {
             	throw new NotImplementedException();
            }

            public object  InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
            {
             	throw new NotImplementedException();
            }

            public bool  IsSynchronous
            {
            	get { return true; }
            }
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            ChannelDispatcher dispatcher = null;

            if(dispatcher == null)
            {
                dispatcher = new ChannelDispatcher(Binding.BuildChannelListener<IReplyChannel>(Address.Uri, "", new BindingParameterCollection()));
            }
            dispatcher.MessageVersion = MessageVersion.None;
            EndpointDispatcher endpointDispatcher = new EndpointDispatcher(Address, "Get", "http://tempuri.org/html");
            endpointDispatcher.AddressFilter = new HttpGetContractFilter();
            endpointDispatcher.ContractFilter = new MatchAllMessageFilter();
            endpointDispatcher.DispatchRuntime.Operations.Add(new DispatchOperation(endpointDispatcher.DispatchRuntime, "Get", "*", "*") { Invoker = new OperationInvoker(), DeserializeRequest = false, SerializeReply = false });
            endpointDispatcher.DispatchRuntime.SingletonInstanceContext = new InstanceContext(serviceHostBase, new HtmlHelp() { Content = Content });
            Type type = Assembly.GetAssembly(typeof(IReplyChannel)).GetType("System.ServiceModel.Dispatcher.SingletonInstanceContextProvider");
            endpointDispatcher.DispatchRuntime.InstanceContextProvider = ((IInstanceContextProvider)Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new object[] { endpointDispatcher.DispatchRuntime }, System.Globalization.CultureInfo.CurrentCulture));
            endpointDispatcher.FilterPriority = 0;
            dispatcher.Endpoints.Add(endpointDispatcher);            

            serviceHostBase.ChannelDispatchers.Add(dispatcher);
        }

        public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {

        }

        public string Content
        {
            get;
            set;
        }

        public class RawContentTypeMapper : WebContentTypeMapper
        {
            public override WebContentFormat GetMessageFormatForContentType(string contentType)
            {
                return WebContentFormat.Raw;
            }
        }

        public class TextMessage : Message
        {
            public TextMessage(string content)
            {
                Content = content;
                Properties[WebBodyFormatMessageProperty.Name] = new WebBodyFormatMessageProperty(WebContentFormat.Raw);
            }

            protected override void OnWriteBodyContents(System.Xml.XmlDictionaryWriter writer)
            {
                byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes( Content );
                writer.WriteBase64(data, 0, data.Length );
            }

            public string Content
            {
                get;
                private set;
            }

            MessageHeaders _headers = new MessageHeaders(MessageVersion.None);
            public override MessageHeaders Headers
            {
                get
                {
                    return _headers;
                }
            }

            MessageProperties _properties = new MessageProperties();
            public override MessageProperties Properties
            {
                get
                {
                    return _properties;
                }
            }

            public override MessageVersion Version
            {
                get
                {
                    return MessageVersion.None;
                }
            }
        }
    }
}
</pre>


<!-- Begin SexyBookmarks Menu Code -->
<div class="sexy-bookmarks sexy-bookmarks-expand sexy-bookmarks-bg-sexy">
<ul class="socials">
		<li class="sexy-delicious">
			<a href="http://delicious.com/post?url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="sexy-digg">
			<a href="http://digg.com/submit?phase=2&amp;url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Digg this!">Digg this!</a>
		</li>
		<li class="sexy-diigo">
			<a href="http://www.diigo.com/post?url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF&amp;desc=Some%20times%20things%20you%20think%20should%20be%20simple%20turn%20out%20to%20take%20quite%20a%20bit%20of%20work%20to%20figure%20out%20how%20to%20do%20with%20WCF.%20One%20of%20those%20things%20is%20serving%20up%20custom%20HTTP%20help%20pages%20for%20your%20service%20endpoints.%20WCF%20ships%20with%20a%20special%20behavior%2C%20the%20ServiceMetadataBehavior%20that%20provides%20the%20functionality%20used" rel="nofollow" title="Post this on Diigo">Post this on Diigo</a>
		</li>
		<li class="sexy-reddit">
			<a href="http://reddit.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="sexy-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="sexy-technorati">
			<a href="http://technorati.com/faves?add=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/" rel="nofollow" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="sexy-mixx">
			<a href="http://www.mixx.com/submit?page_url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Share this on Mixx">Share this on Mixx</a>
		</li>
		<li class="sexy-twitter">
			<a href="http://twitter.com/home?status=Building+Custom+HTTP+Help+Pages+With+WCF+-+http://b2l.me/su25t+&amp;source=shareaholic" rel="nofollow" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="sexy-comfeed">
			<a href="http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/feed" rel="nofollow" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="sexy-misterwong">
			<a href="http://www.mister-wong.com/addurl/?bm_url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;bm_description=Building+Custom+HTTP+Help+Pages+With+WCF&amp;plugin=sexybookmarks" rel="nofollow" title="Add this to Mister Wong">Add this to Mister Wong</a>
		</li>
		<li class="sexy-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;t=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="sexy-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;title=Building+Custom+HTTP+Help+Pages+With+WCF&amp;summary=Some%20times%20things%20you%20think%20should%20be%20simple%20turn%20out%20to%20take%20quite%20a%20bit%20of%20work%20to%20figure%20out%20how%20to%20do%20with%20WCF.%20One%20of%20those%20things%20is%20serving%20up%20custom%20HTTP%20help%20pages%20for%20your%20service%20endpoints.%20WCF%20ships%20with%20a%20special%20behavior%2C%20the%20ServiceMetadataBehavior%20that%20provides%20the%20functionality%20used&amp;source=iServiceOriented" rel="nofollow" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="sexy-newsvine">
			<a href="http://www.newsvine.com/_tools/seed&amp;save?u=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;h=Building+Custom+HTTP+Help+Pages+With+WCF" rel="nofollow" title="Seed this on Newsvine">Seed this on Newsvine</a>
		</li>
		<li class="sexy-friendfeed">
			<a href="http://www.friendfeed.com/share?title=Building+Custom+HTTP+Help+Pages+With+WCF&amp;link=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/" rel="nofollow" title="Share this on FriendFeed">Share this on FriendFeed</a>
		</li>
		<li class="sexy-blogger">
			<a href="http://www.blogger.com/blog_this.pyra?t&amp;u=http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/&amp;n=Building+Custom+HTTP+Help+Pages+With+WCF&amp;pli=1" rel="nofollow" title="Blog this on Blogger">Blog this on Blogger</a>
		</li>
		<li class="sexy-techmeme">
			<a href="http://twitter.com/home/?status=Tip+@Techmeme+http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/+&quot;Building+Custom+HTTP+Help+Pages+With+WCF&quot;" rel="nofollow" title="Tip this to TechMeme">Tip this to TechMeme</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>
<!-- End SexyBookmarks Menu Code -->

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=RmrCIogde2Q:QoB4c418Ngg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=RmrCIogde2Q:QoB4c418Ngg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?i=RmrCIogde2Q:QoB4c418Ngg:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/iserviceoriented/~4/RmrCIogde2Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.iserviceoriented.com/index.php/2010/05/04/building-custom-http-help-pages-with-wcf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Angle Brackets are Dead. Long Live XML.</title>
		<link>http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/</link>
		<comments>http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 21:39:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://blog.iserviceoriented.com/?p=50</guid>
		<description><![CDATA[If you take a look at the XML Information Set specification, you will find this near the top:
“This specification defines an abstract data set called the XML Information Set (Infoset). Its purpose is to provide a consistent set of definitions for use in other specifications that need to refer to the information in a well-formed [...]]]></description>
			<content:encoded><![CDATA[<p>If you take a look at the XML Information Set specification, you will find this near the top:</p>
<blockquote><p>“This specification defines an abstract data set called the XML Information Set (Infoset). Its purpose is to provide a consistent set of definitions for use in other specifications that need to refer to the information in a well-formed XML document.”</p>
<p>http://www.w3.org/TR/xml-infoset/</p></blockquote>
<p>XML is so commonplace today that it is easy to overlook the importance of this statement. One of the core concepts behind XML is the idea of a logical infoset that says nothing about angle brackets and the textual representation that you and I will instantly recognize as an XML document. The logical infoset is little more than a tree of nodes which theoretically can be represented in any number of ways Understanding this is one of the keys to understanding WCF at a deeper level.</p>
<p>If you’ve worked with XML in the .NET framework, you know that there are multiple ways to deal with XML. .NET 1.0 gave us the most commonly used XML classes: the XmlDocument, the XmlReader and the XmlWriter. </p>
<p>If you take a look at the methods exposed by the XmlWriter class, you will notice a lot of what appear to be helper methods. Methods like WriteBase64 and WriteValue take non-text arguments like byte arrays and dates and encode the values into XML representations. For instance, take a look at the following code:</p>
<pre name="code"  class="csharp">
            using (Stream output = File.Create("output.txt"))
            {
                using (XmlWriter xmlWriter = XmlWriter.Create(output))
                {
                     xmlWriter.WriteStartElement("rawBytes");

                    byte[] rawBytes = new byte[1000];
                    byte[] data = new byte[] { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 };
                    data.CopyTo(rawBytes, 0);                    

                    xmlWriter.WriteBase64(rawBytes, 0, rawBytes.Length);
                    xmlWriter.WriteEndElement();
                }
            }
</pre>
<p>Executing this code will produce the following text in the output XML document:</p>
<blockquote><p>&lt;rawBytes&gt;SGVsbG8gV29ybGQhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==&lt;/rawBytes&gt;
</p></blockquote>
<p>No surprises here. Our data is base 64 encoded just like the method implies. However, as I said before, the XML infoset is logical and doesn’t define encoding. What if I had a lot of binary data that I wanted to send to an endpoint, and I didn’t want to waste all those extra bits with base 64 encoding? Maybe I would want to write that base 64 data out without any encoding to save space. </p>
<p>As it turns out, there is a specification for doing exactly that type of thing, which is known as MTOM. MTOM borrows some ideas from e-mail servers, which have been doing this type of thing forever with email attachments and brings the same concept to the XML world. MTOM splits a message up into “MIME parts” which can each be encoded a different way. One part of the message will contain the plain XML, and all the binary data will be moved to its own section, where we don’t have to worry about special characters and encoding. By telling .NET to create an MTOM XML writer instead, we can see how this works:</p>
<pre name="code"  class="csharp">
            using (Stream output = File.Create("output.txt"))
            {
                using (XmlWriter xmlWriter = XmlDictionaryWriter.CreateMtomWriter(output, Encoding.UTF8, Int32.MaxValue, "text/xml"))
                {
                    xmlWriter.WriteStartElement("rawBytes");

                    byte[] rawBytes = new byte[1000];
                    byte[] data = new byte[] { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 };
                    data.CopyTo(rawBytes, 0);                    

                    xmlWriter.WriteBase64(rawBytes, 0, rawBytes.Length);
                    xmlWriter.WriteEndElement();                 

                }
            }
</pre>
<p>Executing this code produces the following output:</p>
<blockquote><p>MIME-Version: 1.0<br />
Content-Type: multipart/related;type=&#8221;application/xop+xml&#8221;;boundary=&#8221;4f98bb98-f37b-412a-b90e-dbe8f939d214+id=1&#8243;;start=&#8221;&lt;http://tempuri.org/0/634011443993914940&gt;&#8221;;start-info=&#8221;text/xml&#8221;</p>
<p>&#8211;4f98bb98-f37b-412a-b90e-dbe8f939d214+id=1<br />
Content-ID: &lt;http://tempuri.org/0/634011443993914940&gt;<br />
Content-Transfer-Encoding: 8bit<br />
Content-Type: application/xop+xml;charset=utf-8;type=&#8221;text/xml&#8221;</p>
<p>&lt;rawBytes&gt;&lt;xop:Include href=&#8221;cid:http%3A%2F%2Ftempuri.org%2F1%2F634011443993924705&#8243; xmlns:xop=&#8221;http://www.w3.org/2004/08/xop/include&#8221;/&gt;&lt;/rawBytes&gt;<br />
&#8211;4f98bb98-f37b-412a-b90e-dbe8f939d214+id=1<br />
Content-ID: &lt;http://tempuri.org/1/634011443993924705&gt;<br />
Content-Transfer-Encoding: binary<br />
Content-Type: application/octet-stream<br />
Hello World!<br />
&#8211;4f98bb98-f37b-412a-b90e-dbe8f939d214+id=1&#8211;
</pre>
</blockquote>
<p>Notice that our XML chunk in the first part of the document has been replaced with a special “XOP” reference node which instructs the recipient that the data can be found in a MIME attachment, and the binary data is no longer base 64 encoded. This looks nothing like the first example and is certainly not the type of XML document you are used to seeing on a daily basis; however, it represents the same logical infoset as the first example. If we had an MTOM reader available (which we do), we could read this document and work with its content the same way as any other XML document. </p>
<p>So let’s extend this idea a little bit. Let’s suppose that we wanted to represent a raw binary file using an XML infoset. How would we represent it? The basic problem should be obvious: most files aren’t XML documents and most files aren’t encoded using MIME parts. But remember that XML and MIME are nothing more than different ways to encode the infoset. If it’s possible to write the binary data as a MIME part, there is no reason we can’t just write the binary data and exclude all the MIME wrappers. To do that, we can create a simple XmlWriter implementation (we’ll leave a lot of the methods unimplemented since our schema doesn’t support anything but our raw binary format):</p>
<pre name="code"  class="csharp">
    public class RawXmlWriter : XmlWriter
    {
        public RawXmlWriter(Stream stream)
        {
            _stream = stream;
        }

        Stream _stream;
        public override void WriteBase64(byte[] buffer, int index, int count)
        {
            _stream.Write(buffer, index, count);
        }

        public override void WriteStartElement(string prefix, string localName, string ns)
        {
            if (localName != "rawBytes")
            {
                throw new InvalidOperationException("This xml writer only supports raw binary data");
            }
        }

        public override void WriteEndElement()
        {

        }

        public override void Close()
        {
            _stream.Close();
        }
   }
</pre>
<p>The rest of the methods, we’ll leave unimplemented, since we are creating a writer which supports a very limited schema. Now we change our code to use our Raw XML Writer:</p>
<pre name="code"  class="csharp">
            using (Stream output = File.Create("output.txt"))
            {
                using (XmlWriter xmlWriter = new RawXmlWriter(output))
                {
                    xmlWriter.WriteStartElement("rawBytes");

                    byte[] rawBytes = new byte[1000];
                    byte[] data = new byte[] { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 };
                    data.CopyTo(rawBytes, 0);                    

                    xmlWriter.WriteBase64(rawBytes, 0, rawBytes.Length);
                    xmlWriter.WriteEndElement();                 

                }
            }
</pre>
<p>And if we take a look at the file on disk, we see the raw bytes from our array written to disk. Creating a RawXmlReader would allow us to read in any file from disk and use its data anywhere we can use an XmlReader.</p>
<p>So what does this have to do with WCF? Well, this is exactly how WCF works under the covers to support multiple forms of message encoding while using infosets to represent the data. When using bindings such as net.tcp, a different implementation of XmlReader and XmlWriter are plugged in which use an optimized XML infoset representation that significantly reduces the overhead imposed by a standard text encoder. When sending data using the REST features of WCF, the WebMessageEncoder uses the same strategy we employed in the final example to read and write raw binary data. </p>
<p>The abstract XML infoset is a powerful concept. By always remembering that the infoset itself is logical, we can enable our application to read or write any format imaginable with a common interface and a simple tree representation.</p>
<p><!-- MH3WURW938PJ --></p>


<!-- Begin SexyBookmarks Menu Code -->
<div class="sexy-bookmarks sexy-bookmarks-expand sexy-bookmarks-bg-sexy">
<ul class="socials">
		<li class="sexy-delicious">
			<a href="http://delicious.com/post?url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="sexy-digg">
			<a href="http://digg.com/submit?phase=2&amp;url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Digg this!">Digg this!</a>
		</li>
		<li class="sexy-diigo">
			<a href="http://www.diigo.com/post?url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML.&amp;desc=If%20you%20take%20a%20look%20at%20the%20XML%20Information%20Set%20specification%2C%20you%20will%20find%20this%20near%20the%20top%3A%0D%0A%0D%0A%E2%80%9CThis%20specification%20defines%20an%20abstract%20data%20set%20called%20the%20XML%20Information%20Set%20%28Infoset%29.%20Its%20purpose%20is%20to%20provide%20a%20consistent%20set%20of%20definitions%20for%20use%20in%20other%20specifications%20that%20need%20to%20refer%20t" rel="nofollow" title="Post this on Diigo">Post this on Diigo</a>
		</li>
		<li class="sexy-reddit">
			<a href="http://reddit.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="sexy-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="sexy-technorati">
			<a href="http://technorati.com/faves?add=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/" rel="nofollow" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="sexy-mixx">
			<a href="http://www.mixx.com/submit?page_url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Share this on Mixx">Share this on Mixx</a>
		</li>
		<li class="sexy-twitter">
			<a href="http://twitter.com/home?status=Angle+Brackets+are+Dead.+Long+Live+XML.+-+http://b2l.me/ftctb+&amp;source=shareaholic" rel="nofollow" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="sexy-comfeed">
			<a href="http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/feed" rel="nofollow" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="sexy-misterwong">
			<a href="http://www.mister-wong.com/addurl/?bm_url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;bm_description=Angle+Brackets+are+Dead.+Long+Live+XML.&amp;plugin=sexybookmarks" rel="nofollow" title="Add this to Mister Wong">Add this to Mister Wong</a>
		</li>
		<li class="sexy-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;t=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="sexy-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;title=Angle+Brackets+are+Dead.+Long+Live+XML.&amp;summary=If%20you%20take%20a%20look%20at%20the%20XML%20Information%20Set%20specification%2C%20you%20will%20find%20this%20near%20the%20top%3A%0D%0A%0D%0A%E2%80%9CThis%20specification%20defines%20an%20abstract%20data%20set%20called%20the%20XML%20Information%20Set%20%28Infoset%29.%20Its%20purpose%20is%20to%20provide%20a%20consistent%20set%20of%20definitions%20for%20use%20in%20other%20specifications%20that%20need%20to%20refer%20t&amp;source=iServiceOriented" rel="nofollow" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="sexy-newsvine">
			<a href="http://www.newsvine.com/_tools/seed&amp;save?u=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;h=Angle+Brackets+are+Dead.+Long+Live+XML." rel="nofollow" title="Seed this on Newsvine">Seed this on Newsvine</a>
		</li>
		<li class="sexy-friendfeed">
			<a href="http://www.friendfeed.com/share?title=Angle+Brackets+are+Dead.+Long+Live+XML.&amp;link=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/" rel="nofollow" title="Share this on FriendFeed">Share this on FriendFeed</a>
		</li>
		<li class="sexy-blogger">
			<a href="http://www.blogger.com/blog_this.pyra?t&amp;u=http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/&amp;n=Angle+Brackets+are+Dead.+Long+Live+XML.&amp;pli=1" rel="nofollow" title="Blog this on Blogger">Blog this on Blogger</a>
		</li>
		<li class="sexy-techmeme">
			<a href="http://twitter.com/home/?status=Tip+@Techmeme+http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/+&quot;Angle+Brackets+are+Dead.+Long+Live+XML.&quot;" rel="nofollow" title="Tip this to TechMeme">Tip this to TechMeme</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>
<!-- End SexyBookmarks Menu Code -->

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=143jrOujrpY:vpaGW9-nXWY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=143jrOujrpY:vpaGW9-nXWY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?i=143jrOujrpY:vpaGW9-nXWY:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/iserviceoriented/~4/143jrOujrpY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.iserviceoriented.com/index.php/2010/02/07/angle-brackets-are-dead-long-live-xml/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Building a Basic Web Server Using WCF</title>
		<link>http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/</link>
		<comments>http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 01:05:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://blog.iserviceoriented.com/?p=41</guid>
		<description><![CDATA[In my last post, I talked about how WCF actually can handle a lot more than basic web service communication. Today, I&#8217;m going to take that a little further, by showing you how you could build a very basic web server on top of WCF.
If you are familiar with ASP.NET, you have probably heard of [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post, I talked about how WCF actually can handle a lot more than basic web service communication. Today, I&#8217;m going to take that a little further, by showing you how you could build a very basic web server on top of WCF.</p>
<p>If you are familiar with ASP.NET, you have probably heard of a little class called IRequestHandler. In ASP.NET, if you wanted to create a handler that simply streamed a file from disk, you might write a little code like this:</p>
<pre name="code"  class="csharp">    public class FileRequestHandler : IHttpHandler
    {
        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false;  }
        }

        public void ProcessRequest(HttpContext context)
        {
            context.Response.WriteFile(context.Request.PhysicalPath);
        }

        #endregion
    }</pre>
<p>This should not be scary at all. Now&#8230; what if we wanted to host a simple web server inside our own application and we wanted to be able to use WCF to call into the interface? It takes a little WCF ninjitsu to make it work, but that&#8217;s what this blog is for.</p>
<p>The first step is creating a binding that will allow raw HTTP communication. To do this, we will create an instance of the CustomBinding class. Most of the bindings that you might be familiar with, such as basicHttpBinding or netTcpBinding hide the internals of WCF and don&#8217;t let you have any clue what is going on under the covers. CustomBinding is not one of those classes. The CustomBinding class allows you to pick and choose transports, security, message encoding (known in WCF terms as &#8220;BindingElements&#8221;) and combine them to do things that the standard bindings won&#8217;t let you do. In this case, we want to tell WCF to combine the HttpTransportBindingElement and the WebMessageEncodingBindingElement. In .NET 4.0 we have a better option&#8230; but most people aren&#8217;t using .NET 4.0 today so I&#8217;ll stick with .NET 3.5 for now. Another possibility would be to write a custom message encoder, but I&#8217;ll try to reuse as much of the built-in classes as possible. One little quirk about the WebMessageEncodingBindingElement is that it defaults to POX support, not raw HTTP. We can change that by adding a custom ContentTypeMapper implementation. To facilitate this process, I&#8217;ve created a BindingFactory class:</p>
<pre name="code"  class="csharp"> public static class BindingFactory
    {
        public static Binding CreateRawHttpBinding()
        {
            HttpTransportBindingElement transport = new HttpTransportBindingElement();
            return new CustomBinding(CreateEncoder(), transport);
        }

        public static WebMessageEncodingBindingElement CreateEncoder()
        {
            WebMessageEncodingBindingElement encoding = new WebMessageEncodingBindingElement();
            encoding.ContentTypeMapper = new RawContentTypeMapper();
            return encoding;
        }

        class RawContentTypeMapper : WebContentTypeMapper
        {
            public override WebContentFormat GetMessageFormatForContentType(string contentType)
            {
                return WebContentFormat.Raw;
            }
        }
    }</pre>
<p>The second thing we are going to need is a ServiceContract. If you read just about any documentation on WCF REST support, you will be lead to believe that you need to add special service behaviors for Url templates and HTTP verbs. Personally, I think all of that nonsense is crap, so we won&#8217;t do that. Instead, we&#8217;ll create a generic contract that can receive any message. Note that this contract is not REST specific. You could actually use the contract to do raw SOAP messaging as well. The way we tell WCF to allow any message to be handled by our contract is to add a method that accept a Message, returns a Message, and has it&#8217;s action and reply action set to &#8220;*&#8221;. This is what it looks like:</p>
<pre name="code" class="csharp">
 [ServiceContract]
    public interface IWebRequestHandler
    {
        [OperationContract(Action="*", ReplyAction="*")]
        Message Request(Message message);
    }
</pre>
<p>When a request comes into our service, we&#8217;ll want the HTTP specific properties from the request to obtain things like the HTTP method and query string. To obtain the HTTP specific information about the request, we can get an HttpRequestMessageProperty from the properties collection of the message. This is pretty simple:</p>
<pre name="code" class="csharp">
  HttpRequestMessageProperty property = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
</pre>
<p>When we create a response message, we&#8217;ll add an HttpResponseMessageProperty for HTTP specific information. To write the response we&#8217;ll create a simple custom message class that can be used to represent our raw binary data. There are two tricks here. The first is that we are adding a WebBodyFormatMessageProperty to the message. This is required because of our choice of MessageEncoder and instructs the message encoder that we will be writing raw binary data. The second trick is that we write out the content as Base64 data. The XmlDictionaryWriter implementation that will be created by the MessageEncoder as a result of the property we have added will write out the Base64 data as raw binary data instead of encoding it. This might seem odd, but there is a very good reason that it works this way. I&#8217;ll save that for a later date.</p>
<pre name="code" class="csharp">
        class RawMessage : Message
        {
            public RawMessage(byte[] data)
            {
                _data = data;

                WebBodyFormatMessageProperty property = new WebBodyFormatMessageProperty(WebContentFormat.Raw);
                Properties.Add(WebBodyFormatMessageProperty.Name, property);
            }

            byte[] _data;

            MessageHeaders _headers = new MessageHeaders(MessageVersion.None);
            public override MessageHeaders Headers
            {
                get { return _headers; }
            }

            protected override void OnWriteBodyContents(System.Xml.XmlDictionaryWriter writer)
            {
                writer.WriteBase64(_data, 0, _data.Length);
            }

            MessageProperties _properties = new MessageProperties();
            public override MessageProperties Properties
            {
                get { return _properties; }
            }

            public override MessageVersion Version
            {
                get { return MessageVersion.None;  }
            }
        }
</pre>
<p>Now we are ready to move on to our simple server implementation. Note that we&#8217;ve marked up the implementation of our interface with an attribute to tell WCF to accept requests to any child path below our endpoint address. </p>
<pre name="code" class="C#">
 [ServiceBehavior(AddressFilterMode=AddressFilterMode.Prefix, InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
    public abstract class WebRequestHandler : IWebRequestHandler
    {
        public WebRequestHandler(Uri address)
        {
            // Ensure there is a trailing slash to our URL to so that MakeRelativeUri will work when we map the URL to a relative path.
            if (!address.ToString().EndsWith("/"))
            {
                address = new Uri(address + "/");
            }
            _address = address;
        }

        Uri _address;        

        MessageEncoder _webEncoder = BindingFactory.CreateEncoder().CreateMessageEncoderFactory().Encoder;

        protected abstract void ProcessRequest(Uri address, HttpRequestMessageProperty requestProperty, TextReader requestBody, HttpResponseMessageProperty responseProperty, TextWriter responseBody);        

        protected string GetRelativePath(Uri address)
        {
            string relativePath = address.LocalPath;
            relativePath = _address.MakeRelativeUri(address).ToString();
            int qIndex = relativePath.IndexOf('?');
            if (qIndex != -1)
            {
                relativePath = relativePath.Substring(0, qIndex);
            }
            return relativePath;
        }

        public System.ServiceModel.Channels.Message Request(System.ServiceModel.Channels.Message message)
        {
            using (MemoryStream responseStream = new MemoryStream())
            {
                using (TextWriter writer = new StreamWriter(responseStream))
                {
                    using (MemoryStream requestStream = new MemoryStream())
                    {
                        _webEncoder.WriteMessage(message, requestStream);
                         byte[] requestData = requestStream.ToArray();

                        using (TextReader reader = new StreamReader(new MemoryStream(requestData, false)))
                        {
                            HttpRequestMessageProperty requestProperty = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];

                            HttpResponseMessageProperty responseProperty = new HttpResponseMessageProperty();

                            ProcessRequest(message.Headers.To, requestProperty, reader, responseProperty, writer);

                            writer.Flush();
                            Message responseMessage = new RawMessage(responseStream.ToArray());
                            responseMessage.Properties[HttpResponseMessageProperty.Name] = responseProperty;
                            return responseMessage;
                        }
                    }
                }
            }
        }
    }
</pre>
<p>So now we have a basic web server class that we can extend. Hooking into the ASP.NET side of things is actually fairly messy and complex in comparison. I&#8217;ve included a very simple implementation in the <a href="http://blog.iserviceoriented.com/wp-content/uploads/2010/01/WebServer.zip">sample project</a> which contains enough logic to execute the simple file handler that this post started with. So there you have it. A raw HTTP host that can respond to web requests and serve up content using WCF.</p>
<p>[Download Sample Project: <a href="http://blog.iserviceoriented.com/wp-content/uploads/2010/01/WebServer.zip">WebServer.zip</a>]</p>


<!-- Begin SexyBookmarks Menu Code -->
<div class="sexy-bookmarks sexy-bookmarks-expand sexy-bookmarks-bg-sexy">
<ul class="socials">
		<li class="sexy-delicious">
			<a href="http://delicious.com/post?url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="sexy-digg">
			<a href="http://digg.com/submit?phase=2&amp;url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Digg this!">Digg this!</a>
		</li>
		<li class="sexy-diigo">
			<a href="http://www.diigo.com/post?url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF&amp;desc=In%20my%20last%20post%2C%20I%20talked%20about%20how%20WCF%20actually%20can%20handle%20a%20lot%20more%20than%20basic%20web%20service%20communication.%20Today%2C%20I%27m%20going%20to%20take%20that%20a%20little%20further%2C%20by%20showing%20you%20how%20you%20could%20build%20a%20very%20basic%20web%20server%20on%20top%20of%20WCF.%0D%0A%0D%0AIf%20you%20are%20familiar%20with%20ASP.NET%2C%20you%20have%20probably%20heard%20of%20a%20lit" rel="nofollow" title="Post this on Diigo">Post this on Diigo</a>
		</li>
		<li class="sexy-reddit">
			<a href="http://reddit.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="sexy-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="sexy-technorati">
			<a href="http://technorati.com/faves?add=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/" rel="nofollow" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="sexy-mixx">
			<a href="http://www.mixx.com/submit?page_url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Share this on Mixx">Share this on Mixx</a>
		</li>
		<li class="sexy-twitter">
			<a href="http://twitter.com/home?status=Building+a+Basic+Web+Server+Using+WCF+-+http://b2l.me/ehehv+&amp;source=shareaholic" rel="nofollow" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="sexy-comfeed">
			<a href="http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/feed" rel="nofollow" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="sexy-misterwong">
			<a href="http://www.mister-wong.com/addurl/?bm_url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;bm_description=Building+a+Basic+Web+Server+Using+WCF&amp;plugin=sexybookmarks" rel="nofollow" title="Add this to Mister Wong">Add this to Mister Wong</a>
		</li>
		<li class="sexy-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;t=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="sexy-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;title=Building+a+Basic+Web+Server+Using+WCF&amp;summary=In%20my%20last%20post%2C%20I%20talked%20about%20how%20WCF%20actually%20can%20handle%20a%20lot%20more%20than%20basic%20web%20service%20communication.%20Today%2C%20I%27m%20going%20to%20take%20that%20a%20little%20further%2C%20by%20showing%20you%20how%20you%20could%20build%20a%20very%20basic%20web%20server%20on%20top%20of%20WCF.%0D%0A%0D%0AIf%20you%20are%20familiar%20with%20ASP.NET%2C%20you%20have%20probably%20heard%20of%20a%20lit&amp;source=iServiceOriented" rel="nofollow" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="sexy-newsvine">
			<a href="http://www.newsvine.com/_tools/seed&amp;save?u=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;h=Building+a+Basic+Web+Server+Using+WCF" rel="nofollow" title="Seed this on Newsvine">Seed this on Newsvine</a>
		</li>
		<li class="sexy-friendfeed">
			<a href="http://www.friendfeed.com/share?title=Building+a+Basic+Web+Server+Using+WCF&amp;link=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/" rel="nofollow" title="Share this on FriendFeed">Share this on FriendFeed</a>
		</li>
		<li class="sexy-blogger">
			<a href="http://www.blogger.com/blog_this.pyra?t&amp;u=http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/&amp;n=Building+a+Basic+Web+Server+Using+WCF&amp;pli=1" rel="nofollow" title="Blog this on Blogger">Blog this on Blogger</a>
		</li>
		<li class="sexy-techmeme">
			<a href="http://twitter.com/home/?status=Tip+@Techmeme+http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/+&quot;Building+a+Basic+Web+Server+Using+WCF&quot;" rel="nofollow" title="Tip this to TechMeme">Tip this to TechMeme</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>
<!-- End SexyBookmarks Menu Code -->

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=SSlUrs6lF0g:PYl2J9bRdVE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=SSlUrs6lF0g:PYl2J9bRdVE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?i=SSlUrs6lF0g:PYl2J9bRdVE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/iserviceoriented/~4/SSlUrs6lF0g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.iserviceoriented.com/index.php/2010/01/23/building-a-basic-web-server-using-wcf/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Message: The Most Important WCF Class</title>
		<link>http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/</link>
		<comments>http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 09:17:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[WCF]]></category>
		<category><![CDATA[Basics]]></category>
		<category><![CDATA[Message]]></category>

		<guid isPermaLink="false">http://blog.iserviceoriented.com/?p=8</guid>
		<description><![CDATA[Even fairly experienced WCF programmers may never have had to deal with this little gem, however, it is the single most important class in the WCF framework. Why is that? Because the message class provides the fundamental abstraction which represents all data sent or received from any WCF endpoint.
Key Parts
There are four key parts to [...]]]></description>
			<content:encoded><![CDATA[<pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">Even fairly experienced WCF programmers may never have had to deal with this little gem, however, it is the single most important class in the WCF framework. Why is that? Because the message class provides the fundamental abstraction which represents all data sent or received from any WCF endpoint.</span></pre>
<h1>Key Parts</h1>
<p>There are four key parts to the message class:</p>
<ul>
<li><strong>Version </strong>- The version property contains information about the SOAP and Addressing versions used by the message. WCF fully supports use of non-SOAP messages for which this property is will be None to indicate the lack of any special formatting.</li>
<li><strong>Properties </strong>- Message properties contain processing information about the message which will not be written to the underlying transport stream as part of the message content. One example of what message properties can be used for is controlling things like HTTP verbs and status codes.</li>
<li><strong>Headers </strong>- A collection of message headers. A few common headers such as To and Action can be accessed via shortcut properties in the headers collection.</li>
<li><strong>Body </strong>- You can&#8217;t actually access the message body because the Message class abstraction is mean to be used as if the content of the Message was a stream.</li>
</ul>
<h1>It&#8217;s Abstract</h1>
<p>This will come as a surprise to many people, because the WCF framework does a very good job of hiding this fact, but the Message class itself is an abstract class. So put away any preconceived notions you might have had about how WCF at it&#8217;s core can only be used for web services and XML based communication. The fact is that you could create a message class backed directly by a raw binary array if you didn&#8217;t want any kind of performance hit for loading the data&#8230; as a matter of fact you probably wouldn&#8217;t want to even waste your time doing that, because WCF does exactly that when you are using many of the default settings! Actually&#8230; it does it even more efficiently than you would probably do it on your own by taking advantage of buffer managers to reduce the number of allocations that need to be made as messages are being created and disposed. So, despite the fact that the underlying abstraction is streaming, WCF actually buffers messages into a byte array by default to allow for higher performance.</p>
<h1>It&#8217;s Streaming</h1>
<p>Once you read the message, it cannot be read again. For this reason, all custom message classes must also provide a MessageBuffer implementation. I won&#8217;t talk much about the MessageBuffer class at this point, other than to say that it is also abstract and it is responsible for creating additional &#8220;copies&#8221; of the message. I say &#8220;copies&#8221; because the default implementations that are most commonly used by the standard bindings won&#8217;t actually &#8220;copy&#8221; anything. They just return another instance backed by the same internal byte array. This makes for ultra efficient message copying, but is only possible because of another trait of the message&#8230; The reason Message implementers must provide their own MessageBuffer implementations is so that the copy operation itself can be as optimized as possible.</p>
<h1><strong>It&#8217;s Immutable</strong></h1>
<p>Well&#8230; sort of. The properties and headers of the message can be modified at will, making things like routing logic and header processing much easier to deal with, but the message body itself cannot be modified using the Message or MessageBuffer classes. For this reason, many hooks  in the WCF internals where a Message might need to by modified will pass the message as a ref parameter so it can be swapped for another message.</p>
<h1>It&#8217;s Not XML</h1>
<p>The last basic thing you need to know about the Message class which I already touched on, but should make clear again&#8230; the Message class does have to not represent XML data! This may seem like a strange statement if you&#8217;ve looked casually at the methods provided by the message class. However, this is only due to the unfortunate naming that the WCF team chose for XmlDictionaryReader and XmlDictionaryWriter, which have a lot of methods for reading and writing XML data, but fully support reading and writing raw binary content as well.</p>


<!-- Begin SexyBookmarks Menu Code -->
<div class="sexy-bookmarks sexy-bookmarks-expand sexy-bookmarks-bg-sexy">
<ul class="socials">
		<li class="sexy-delicious">
			<a href="http://delicious.com/post?url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="sexy-digg">
			<a href="http://digg.com/submit?phase=2&amp;url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Digg this!">Digg this!</a>
		</li>
		<li class="sexy-diigo">
			<a href="http://www.diigo.com/post?url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class&amp;desc=Even%20fairly%20experienced%20WCF%20programmers%20may%20never%20have%20had%20to%20deal%20with%20this%20little%20gem%2C%20however%2C%20it%20is%20the%20single%20most%20important%20class%20in%20the%20WCF%20framework.%20Why%20is%20that%3F%20Because%20the%20message%20class%20provides%20the%20fundamental%20abstraction%20which%20represents%20all%20data%20sent%20or%20received%20from%20any%20WCF%20endpoint.%0D" rel="nofollow" title="Post this on Diigo">Post this on Diigo</a>
		</li>
		<li class="sexy-reddit">
			<a href="http://reddit.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="sexy-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="sexy-technorati">
			<a href="http://technorati.com/faves?add=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/" rel="nofollow" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="sexy-mixx">
			<a href="http://www.mixx.com/submit?page_url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Share this on Mixx">Share this on Mixx</a>
		</li>
		<li class="sexy-twitter">
			<a href="http://twitter.com/home?status=Message%3A+The+Most+Important+WCF+Class+-+http://b2l.me/ec7fy+&amp;source=shareaholic" rel="nofollow" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="sexy-comfeed">
			<a href="http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/feed" rel="nofollow" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="sexy-misterwong">
			<a href="http://www.mister-wong.com/addurl/?bm_url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;bm_description=Message%3A+The+Most+Important+WCF+Class&amp;plugin=sexybookmarks" rel="nofollow" title="Add this to Mister Wong">Add this to Mister Wong</a>
		</li>
		<li class="sexy-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;t=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="sexy-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;title=Message%3A+The+Most+Important+WCF+Class&amp;summary=Even%20fairly%20experienced%20WCF%20programmers%20may%20never%20have%20had%20to%20deal%20with%20this%20little%20gem%2C%20however%2C%20it%20is%20the%20single%20most%20important%20class%20in%20the%20WCF%20framework.%20Why%20is%20that%3F%20Because%20the%20message%20class%20provides%20the%20fundamental%20abstraction%20which%20represents%20all%20data%20sent%20or%20received%20from%20any%20WCF%20endpoint.%0D&amp;source=iServiceOriented" rel="nofollow" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="sexy-newsvine">
			<a href="http://www.newsvine.com/_tools/seed&amp;save?u=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;h=Message%3A+The+Most+Important+WCF+Class" rel="nofollow" title="Seed this on Newsvine">Seed this on Newsvine</a>
		</li>
		<li class="sexy-friendfeed">
			<a href="http://www.friendfeed.com/share?title=Message%3A+The+Most+Important+WCF+Class&amp;link=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/" rel="nofollow" title="Share this on FriendFeed">Share this on FriendFeed</a>
		</li>
		<li class="sexy-blogger">
			<a href="http://www.blogger.com/blog_this.pyra?t&amp;u=http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/&amp;n=Message%3A+The+Most+Important+WCF+Class&amp;pli=1" rel="nofollow" title="Blog this on Blogger">Blog this on Blogger</a>
		</li>
		<li class="sexy-techmeme">
			<a href="http://twitter.com/home/?status=Tip+@Techmeme+http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/+&quot;Message%3A+The+Most+Important+WCF+Class&quot;" rel="nofollow" title="Tip this to TechMeme">Tip this to TechMeme</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>
<!-- End SexyBookmarks Menu Code -->

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=Rkja51z2-Hw:hcUMxqKb_ck:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=Rkja51z2-Hw:hcUMxqKb_ck:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?i=Rkja51z2-Hw:hcUMxqKb_ck:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/iserviceoriented/~4/Rkja51z2-Hw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.iserviceoriented.com/index.php/2010/01/22/message-the-most-important-class-in-wcf/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Back in Action</title>
		<link>http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/</link>
		<comments>http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 07:41:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.iserviceoriented.com/?p=4</guid>
		<description><![CDATA[It&#8217;s been over a year since the last time I wrote a blog post. Been living WCF 24/7 since then and people keep telling me to start blogging again. So today, I&#8217;m finally going to give in.





		
			Share this on del.icio.us
		
		
			Digg this!
		
		
			Post this on Diigo
		
		
			Share this on Reddit
		
		
			Stumble upon something good? Share it on StumbleUpon
		
		
			Share this [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been over a year since the last time I wrote a blog post. Been living WCF 24/7 since then and people keep telling me to start blogging again. So today, I&#8217;m finally going to give in.</p>


<!-- Begin SexyBookmarks Menu Code -->
<div class="sexy-bookmarks sexy-bookmarks-expand sexy-bookmarks-bg-sexy">
<ul class="socials">
		<li class="sexy-delicious">
			<a href="http://delicious.com/post?url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action" rel="nofollow" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="sexy-digg">
			<a href="http://digg.com/submit?phase=2&amp;url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action" rel="nofollow" title="Digg this!">Digg this!</a>
		</li>
		<li class="sexy-diigo">
			<a href="http://www.diigo.com/post?url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action&amp;desc=It%27s%20been%20over%20a%20year%20since%20the%20last%20time%20I%20wrote%20a%20blog%20post.%20Been%20living%20WCF%2024%2F7%20since%20then%20and%20people%20keep%20telling%20me%20to%20start%20blogging%20again.%20So%20today%2C%20I%27m%20finally%20going%20to%20give%20in." rel="nofollow" title="Post this on Diigo">Post this on Diigo</a>
		</li>
		<li class="sexy-reddit">
			<a href="http://reddit.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action" rel="nofollow" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="sexy-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action" rel="nofollow" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="sexy-technorati">
			<a href="http://technorati.com/faves?add=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/" rel="nofollow" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="sexy-mixx">
			<a href="http://www.mixx.com/submit?page_url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action" rel="nofollow" title="Share this on Mixx">Share this on Mixx</a>
		</li>
		<li class="sexy-twitter">
			<a href="http://twitter.com/home?status=Back+in+Action+-+http://b2l.me/ec542+&amp;source=shareaholic" rel="nofollow" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="sexy-comfeed">
			<a href="http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/feed" rel="nofollow" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="sexy-misterwong">
			<a href="http://www.mister-wong.com/addurl/?bm_url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;bm_description=Back+in+Action&amp;plugin=sexybookmarks" rel="nofollow" title="Add this to Mister Wong">Add this to Mister Wong</a>
		</li>
		<li class="sexy-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;t=Back+in+Action" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="sexy-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;title=Back+in+Action&amp;summary=It%27s%20been%20over%20a%20year%20since%20the%20last%20time%20I%20wrote%20a%20blog%20post.%20Been%20living%20WCF%2024%2F7%20since%20then%20and%20people%20keep%20telling%20me%20to%20start%20blogging%20again.%20So%20today%2C%20I%27m%20finally%20going%20to%20give%20in.&amp;source=iServiceOriented" rel="nofollow" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="sexy-newsvine">
			<a href="http://www.newsvine.com/_tools/seed&amp;save?u=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;h=Back+in+Action" rel="nofollow" title="Seed this on Newsvine">Seed this on Newsvine</a>
		</li>
		<li class="sexy-friendfeed">
			<a href="http://www.friendfeed.com/share?title=Back+in+Action&amp;link=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/" rel="nofollow" title="Share this on FriendFeed">Share this on FriendFeed</a>
		</li>
		<li class="sexy-blogger">
			<a href="http://www.blogger.com/blog_this.pyra?t&amp;u=http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/&amp;n=Back+in+Action&amp;pli=1" rel="nofollow" title="Blog this on Blogger">Blog this on Blogger</a>
		</li>
		<li class="sexy-techmeme">
			<a href="http://twitter.com/home/?status=Tip+@Techmeme+http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/+&quot;Back+in+Action&quot;" rel="nofollow" title="Tip this to TechMeme">Tip this to TechMeme</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>
<!-- End SexyBookmarks Menu Code -->

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=AIjVOtp9ZUw:jky0Qf7S5i0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/iserviceoriented?a=AIjVOtp9ZUw:jky0Qf7S5i0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/iserviceoriented?i=AIjVOtp9ZUw:jky0Qf7S5i0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/iserviceoriented/~4/AIjVOtp9ZUw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.iserviceoriented.com/index.php/2010/01/21/back-in-action/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
