
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head id="Head1"><title>
	Windows Live Writer RULES
</title><link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon" /><link rel="stylesheet" type="text/css" href="/Resource_/Style/October2008/default.css" /><link id="rssLink" rel="alternate" type="application/rss+xml" title="NetFX Harmonics Feed" href="http://feeds2.feedburner.com/FXHarmonics/" /><link id="rsd" rel="EditURI" type="application/rsd+xml" href="http://www.netfxharmonics.comrsd.xml" /><link id="wlwmanifest" rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://www.netfxharmonics.comwlwmanifest.xml" /></head>
<body>
    
    <div id="header">
        <h1 id="image" class="title-image" onclick="window.location=&#39;http://www.netfxharmonics.com/&#39;">
        </h1>
        <h1 id="text">
            <a id="hlBlogUrl" href="http://www.netfxharmonics.com/">NetFXHarmonics (Online Home of David Betz [MVP])</a>
        </h1>
        <p id="description">
            { David Betz' Home for AJAX, Silverlight, and .NET Technology, Architecture, and Elegance }
        </p>
       
    </div>
    <ul id="bar">
        <li class="first-bar-item"><a href="/">Home</a></li>
        <li><a href="/index/2009">Site Index</a></li>
        <li><a href="http://www.themeliapro.com/">Themelia Pro</a></li>
        <li><a href="/devserver">DevServer</a></li>
        <li><a href="/minima">Minima</a></li>
        <li><a href="https://mvp.support.microsoft.com/profile/David.Betz">Microsoft MVP</a></li>
        <li><a href="/Resource_/Pdf/LinkedInResume.pdf">Résumé (pdf)</a></li>
    </ul>
    <div id="main">
        <div id="sidebar">
            <div id="mvpLogo">
                <a href="http://mvp.support.microsoft.com/">
                    <img src="/Resource_/Image/MVP_Horizontal_FullColor.png" alt="Microsoft MVP" />
                </a>
            </div>
        <div id="email">
            <a href="http://www.linkedin.com/in/davidbetz"><img src="/Resource_/Image/btn_profile_greytxt_80x15.gif" alt="LinkedIn" /></a>
            <a href="http://2idi.com/contact/=david.betz"><img src="/Resource_/Image/EMailButton.png" alt="e-mail" /></a>
        </div>
            <div id="translator">
                <span>Want a different language?</span><br />
                <script type="text/javascript" src="http://translator.live.com/TranslatePageLink.aspx?pl=en"></script>
            </div>
            <div id="sidebarInner">
                
<ul id="verse">
<!--<script type="text/javascript" src="http://www.gnpcb.org/esv/share/js/?action=doPassageQuery&amp;passage=php+3:8&amp;include-verse-numbers=false"></script>-->
<script type="text/javascript" src="http://www.gnpcb.org/esv/share/js/?action=doPassageQuery&amp;passage=2+tim+3:16&amp;include-verse-numbers=false"></script>
</ul>
                <span id="hh01_InfoBlock2" ShowFeedIcon="false"><div class="InformationBlock"><h2>Most Popular</h2><ul><li><a href="http://www.themeliapro.com/">Development: Themelia Pro 2.0</a></li><li><a href="http://www.netfxharmonics.com/devserver">Web Server: DevServer 1.1</a></li><li><a href="http://www.netfxharmonics.com/minima">Training: Minima Blog Engine 3.3</a></li><li><a href="http://www.netfxharmonics.com/2007/11/ESV-Bible-Web-Service-20-Framework-for-NET-35">API: ESV Bible .NET 3.5 Client</a></li><li><a href="http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2">Article: WCF in Silverlight 2</a></li><li><a href="http://www.netfxharmonics.com/2008/12/Reusing-NET-Assemblies-in-Silverlight">Article: Reusing .NET in Silverlight</a></li></ul><div class="BlockFooter"></div></div></span>
                <h2>Label Cloud</h2><div id="labels"><span style="font-size:18pt"><a href="http://www.netfxharmonics.com/label/javascriptajax">AJAX </a></span><span style="font-size:16pt"><a href="http://www.netfxharmonics.com/label/aspnet">ASP.NET </a></span><span style="font-size:7pt"><a href="http://www.netfxharmonics.com/label/csharp">C# </a></span><span style="font-size:7pt"><a href="http://www.netfxharmonics.com/label/debugging">Debugging </a></span><span style="font-size:7pt"><a href="http://www.netfxharmonics.com/label/exceptions">Exceptions </a></span><span style="font-size:12pt"><a href="http://www.netfxharmonics.com/label/firefox">Firefox </a></span><span style="font-size:8pt"><a href="http://www.netfxharmonics.com/label/llblgen">LLBLGen Pro </a></span><span style="font-size:9pt"><a href="http://www.netfxharmonics.com/label/projects">Projects </a></span><span style="font-size:7pt"><a href="http://www.netfxharmonics.com/label/services">Services </a></span><span style="font-size:15pt"><a href="http://www.netfxharmonics.com/label/silverlight">Silverlight </a></span><span style="font-size:16pt"><a href="http://www.netfxharmonics.com/label/training">Training </a></span><span style="font-size:10pt"><a href="http://www.netfxharmonics.com/label/videos">Videos </a></span><span style="font-size:12pt"><a href="http://www.netfxharmonics.com/label/wcf">WCF </a></span><span style="font-size:7pt"><a href="http://www.netfxharmonics.com/label/wpf">WPF </a></span><span style="font-size:7pt"><a href="http://www.netfxharmonics.com/label/xag">XAG </a></span><span style="font-size:9pt"><a href="http://www.netfxharmonics.com/label/xhtmlcss">XHTML/CSS </a></span></div>
                <h2>Archives</h2><ul id="recent"><li><a href="/2009/07">July 2009</a></li><li><a href="/2009/06">June 2009</a></li><li><a href="/2009/03">March 2009</a></li><li><a href="/2009/01">January 2009</a></li><li><a href="/2008/12">December 2008</a></li><li><a href="/2008/11">November 2008</a></li><li><a href="/2008/10">October 2008</a></li><li><a href="/2008/04">April 2008</a></li><li><a href="/2008/03">March 2008</a></li><li><a href="/2008/02">February 2008</a></li><li><a href="/2008/01">January 2008</a></li><li><a href="/2007/12">December 2007</a></li><li><a href="/2007/11">November 2007</a></li><li><a href="/2007/10">October 2007</a></li><li><a href="/2007/09">September 2007</a></li><li><a href="/2007/08">August 2007</a></li><li><a href="/2007/07">July 2007</a></li><li><a href="/2007/06">June 2007</a></li><li><a href="/2007/05">May 2007</a></li><li><a href="/2007/04">April 2007</a></li><li><a href="/2007/03">March 2007</a></li><li><a href="/2007/02">February 2007</a></li><li><a href="/2007/01">January 2007</a></li><li><a href="/2006/12">December 2006</a></li><li><a href="/2006/10">October 2006</a></li><li><a href="/2006/09">September 2006</a></li><li><a href="/2006/06">June 2006</a></li><li><a href="/2006/05">May 2006</a></li><li><a href="/2006/04">April 2006</a></li><li><a href="/2006/03">March 2006</a></li><li><a href="/2006/02">February 2006</a></li><li><a href="/2006/01">January 2006</a></li><li><a href="/2005/12">December 2005</a></li><li><a href="/2005/11">November 2005</a></li><li><a href="/2005/10">October 2005</a></li></ul>
                
                
            </div>
            <p id="browseHappy"><a href="http://browsehappy.com/" title="Browse Happy: Switch to a safer browser today"><img src="/Resource_/Image/bh_150x40.gif" alt="Browse Happy logo" width="150" height="40"></a></p>
            <p id="firefoxIcon">
                <a href="http://www.amazon.com/gp/registry/wishlist/2J5ZML8CH7D9I/ref=wl_web"><img src="http://g-ecx.images-amazon.com/images/G/01/gifts/registries/wishlist/v2/web/wl-btn-129-b._V46776269_.gif" width="129" alt="My Amazon.com Wish List" height="42" border="0" /></a>
                
                <br />
                <a href="http://www.sudokian.com"><img src="/Resource_/Image/SmallSudokianLogo.png" alt="Sudokian.com" /></a>
                <br/>
                <a href="http://www.themeliapro.com/"><img src="/Resource_/Image/GetTHemeliaBadge.png" alt="get themelia" /></a>
            </p>
            <p id="feeds">
                <a id="hlFeedUrl1" title="Subscribe to my feed" rel="alternate" type="application/rss+xml" href="http://feeds2.feedburner.com/FXHarmonics/">
                    <img src="http://www.feedburner.com/fb/images/pub/feed-icon32x32.png" alt="" style="border: 0" />
                </a>
            </p>
            <div id="googleAdsense">
            </div>
        </div>
        <div id="content">
            <script src="/Resource_/Lib/jquery-1.4.1.js" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7aHj61NEB12h1MBnZn_JOrD2UgtCb0fwlD8XCZ2V3phIg2&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7aHj61NEB12h1MBnZn_JOrDs4Xdm73FXU7jR62FDdFkbg2&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7aHj61NEB12h1MBnZn_JOrD9OybmWWUoS65CNvtc8o3Hw2&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7aHj61NEB12h1MBnZn_JOrDAx8JLnsFcg7MBH-RnHkEMQ2&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7abXQvkL0JGmorrJpHGVSTVYFUWPO0RZB4JRHWgPBkzlQ2&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7abXQvkL0JGmorrJpHGVSTVmfbtLD9AO-Gs37u6m9r3Xp1hlTZ0266UNPyHB6aSTkA1&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/WebResource.axd?d=mWr5Q-wtS6MSyAHHU4kkDlV9TxDQ1Osd6g_hLl_TC7aXR6NEZp5In55Gspx9GQyet1NXf9m_RMmA98yPFkdNbw2&amp;t=634013225127414635" type="text/javascript"></script>
<script src="/Resource_/Code/Configuration.js" type="text/javascript"></script>
<script src="/Resource_/Code/Initialization.js" type="text/javascript"></script><script type="text/javascript">

$(function( ) {
Initialization.init()

});

$(window).bind('load', function( ) {

});



$(function( ) {

});

$(window).bind('load', function( ) {

});


</script>
                <p class="announcement">Want to follow this site?  <a id="hlFeedUrl2" title="Subscribe to my feed" rel="alternate" type="application/rss+xml" href="http://feeds2.feedburner.com/FXHarmonics/">Here's the RSS feed.</a></p>
                <input type="hidden" name="rptPosts$ctl00$hBlogEntryGuid" id="rptPosts_ctl00_hBlogEntryGuid" value="C5D9D7DE-518A-4985-BD47-D709C82EEC72" />
<div class="post">
    <h3><a href="http://www.netfxharmonics.com/2007/07/Windows-Live-Writer-RULES">Windows Live Writer RULES</a></h3>
    <h2 class="date-header">Monday, July 30, 2007</h2>
    <div class="post-body">
        <div><p>Microsoft Windows Live Writer (Beta 2) is by far and away one of the coolest tools I've used in a long time.&nbsp; Since I created Minima, I was using my own extremely lame WPF app to do all my posting and it made posting a bore.&nbsp; I've been meaning to put some time into making a more interesting WPF app, but instead Windows Live Writer saved the day.&nbsp; With this thing I can post new entries, save drafts, set labels, as well as view and edit previous entries.</p> <p>&nbsp;Having said all that, setting it up wasn't that easy.&nbsp; Well, the setup was simple, but figuring out what to setup wasn't.&nbsp; I kept thinking that there was some .NET interface you had to implement, because the documentation kept talking about it's API and gave COM and .NET examples.&nbsp; Well as it turns out, all you have to do is implement a well known blogging API and point WLW to it!&nbsp; In my case, I chose the Metaweblog API.</p> <p>Setting this API was actually rather simple, though it took some experimentation at first as I've never worked with the API at first.&nbsp; Also, this API uses XML-RPC calls and at first and, at first, I figured I would have to write the XML listener and all XML messages manually.&nbsp; It turns out that there's a nice API called XML-RPC.NET.&nbsp; You set this up similar to how you setup a WCF service: via interfaces.</p> <p>Here's the basic idea behind the XML-RPC.NET API:</p><pre class="code">[<span style="color: rgb(0,128,128)">XmlRpcService</span>(Name = <span style="color: rgb(128,0,0)">"Minima API"</span>, AutoDocumentation = <span style="color: rgb(0,0,255)">true</span>)]
[<span style="color: rgb(0,128,128)">XmlRpcUrl</span>(<span style="color: rgb(128,0,0)">"http://www.netfxharmonics.com/xml-rpc/"</span>)]

<span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">class</span> <span style="color: rgb(0,128,128)">XmlRpcApi</span> : <span style="color: rgb(0,128,128)">XmlRpcService
</span>{
    [<span style="color: rgb(0,128,128)">XmlRpcMethod</span>(<span style="color: rgb(128,0,0)">"blogger.getUsersBlogs"</span>)]
    <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,128,128)">BlogInfo</span>[] GetUsersBlogs(<span style="color: rgb(0,128,128)">String</span> key, <span style="color: rgb(0,128,128)">String</span> username, <span style="color: rgb(0,128,128)">String</span> password) {
        <span style="color: rgb(0,128,0)">// Stuff goes here
</span>    }
}</pre>
<p>You just set two class-level attributes and then set a method-level on each method.&nbsp; Then you expose this class as an HttpHandler as the XmlRpcService class this class is inheriting from actually implements the IHttpHandler interface, which is rather convenient.</p>
<p>How did I know what methods I had to implement?&nbsp; Well, the Metaweblog API "specification" is NOT a real specification, it's just an article that only mentions parts of it.&nbsp; Also, XML-RPC.NET doesn't seem to have any useful tracing abilities, so that was out.&nbsp; After&nbsp;a while though, I just found someone else's web site that implements the Metaweblog API and looked their API documentation (you can just look at the sample API below).&nbsp; It turns out that to use the Metaweblog API means you will be using parts of the Blogger API as well.&nbsp; Interesting...</p>
<p>Being a minimalist though, I wasn't about to implement ALL functionality.&nbsp; So I setup an ASPX page that took the Request.InputStream, pointed WLW at the page, and when WLW did a request I got an e-mail from my ASPX page.&nbsp; When I saw that WLW was calling a specific function, I implemented that specific one.&nbsp; Of course I also had to implement specific data structures as well.&nbsp; Really though, all you have to do is use XML-RPC.NET to implement the functions it wants and give it the structures in the Metaweblog API (as you can see in the sample API below) and you're done.</p>
<p>[As a side note, if you aren't familiar with what I mean by accessing the Request.InputStream steam, this stream contains the information that comes to the ASPX page in the POST portion of the HTTP request.&nbsp; You will often access this when you are creating manual XML services (see my XmlHttp Interop article below for an example).&nbsp; Here is an example of getting the input stream:</p><pre class="code"><span style="color: rgb(0,128,128)">Byte</span>[] buffer = <span style="color: rgb(0,0,255)">new</span> <span style="color: rgb(0,128,128)">Byte</span>[context.Request.InputStream.Length];
context.Request.InputStream.Read(buffer, 0, (<span style="color: rgb(0,128,128)">Int32</span>)context.Request.InputStream.Length);
<span style="color: rgb(0,128,128)">String</span> postData = <span style="color: rgb(0,128,128)">ASCIIEncoding</span>.UTF8.GetString(buffer);</pre>
<p>You could use something like this to view what information is being sent from WLW.]</p>
<p>In my debugging I found that WLW has a tremendous number of extremely weird bugs.&nbsp; For example, one of the structures I needed to implement was a structure called "Post" (I'm using the term structure, but it's just XML over the wire and it's a class in my API-- not a struct).&nbsp; However, WLW would give me errors if some of the fields were null and would give me a different error if they weren't null, but even then, it was only one some functions.&nbsp; So I had to create two versions of "Post".&nbsp; One called "Post" which only had a few members, and the other called "FullPost", which had everything.&nbsp; Strange.&nbsp; Oh well... I've seen worst (ever use Internet Explorer?)</p>

<p>In the end though, WLW was talking seamlessly with my API.&nbsp;  I was really, really dreading making a better blog client as that felt like such a waste of time (and there was NO way I was going to use a web client-- WPF RULES!). Windows Live Writer (Beta 2) has already been a great help for me in the past week.  Not just WLW itself though, but also some of the great plugins you can use with it.  For example, in this write-up, I used a Visual Studio pasting plugin to allow me to copy from VS2005 and paste here to get fancy color syntax.  Cool!</p>

<p>Related Links</p>
<ul>
<li class="external-link"><a href="http://writer.live.com">Windows Live Writer</a> 
<li class="local-website"><a href="http://mms.jampadtechnology.com/xml-rpc/">Minima API Sample</a> 
<li class="website"><a href="http://www.xml-rpc.net/">XML-RPC.NET</a> 
<li class="article"><a href="http://www.netfxharmonics.com/articles/XmlHttpServiceInterop/part1.aspx">XmlHttp Service Interop (Part 1)</a></li></ul></div>
    </div>
    <p class="post-footer">

<div class="feedburner-tracker">
<script src="http://feeds.feedburner.com/~s/FXHarmonics?i=http://www.netfxharmonics.com/2007/07/Windows-Live-Writer-RULES" type="text/javascript" charset="utf-8">
</script>
</div>


    </p>
</div>
        </div>
    </div>
    
<div id="license">
    
<p>
<!--Creative Commons License-->
<a rel="license" href="http://creativecommons.org/licenses/by/2.5/">
<img alt="Creative Commons License" style="border-width: 0" src="http://creativecommons.org/images/public/somerights20.png"/></a><br/>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5  License</a>.
<!--/Creative Commons License-->
<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
	<Work rdf:about="">
		<license rdf:resource="http://creativecommons.org/licenses/by/2.5/" />
	</Work>
	<License rdf:about="http://creativecommons.org/licenses/by/2.5/"><permits rdf:resource="http://web.resource.org/cc/Reproduction"/><permits rdf:resource="http://web.resource.org/cc/Distribution"/><requires rdf:resource="http://web.resource.org/cc/Notice"/><requires rdf:resource="http://web.resource.org/cc/Attribution"/><permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/></License></rdf:RDF> -->
</p>

    <p>Built on <a href ="http://www.themeliapro.com/">Themelia Pro 2.0</a></p>
    
    
    <p id="silk-icons-reference">Mini-icons are part of the Silk Icons set of icons at <a href="http://www.famfamfam.com/lab/icons/silk/">famfamfam.com</a></p>
</div>
    <div id="footer">
        <a href="http://www.spreadfirefox.com/?q=affiliates&amp;id=72158&amp;t=202">
            <img alt="Upgrade to Firefox 3.0!" title="Upgrade to Firefox 3.0!" src="http://sfx-images.mozilla.org/affiliates/products/firefox/upgrade_1_5_468b1.jpg" />
        </a>
    </div>
    <script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-251537-4");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>