<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">JobServe Labs - Articles in Technical</title><subtitle type="text">Articles in Technical from the JobServe Labs blog</subtitle><id>http://js001008.jobserve.com/jslabs.svc/feed/Technical</id><updated>2012-02-09T22:53:06Z</updated><link rel="alternate" href="http://www.labs.jobserve.com/AllArticles.aspx?pNo=1"/><link rel="self" type="application/atom+xml" href="http://www.labs.jobserve.com/jslabs.svc/feed/Technical?format=atom&amp;page=1&amp;pageSize=20"/><entry><id>931c351e-3181-40e0-bd24-ea486b85b959</id><title type="text">We help Microsoft fix Visual 2010 Help Manager</title><updated>2010-02-10T11:33:56Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/We-help-Microsoft-fix-Visual-2010-Help-Manager"/><category term="Technical"/><content type="html">&lt;p&gt;In a previous post we described &lt;a href="http://www.labs.jobserve.com/Articles.aspx/VS2010-Beta-2--Fatal-Error-Occurred-installing-Help" target="_blank"&gt;a bug in the VS2010 Beta 2 MSDN product which prevents you from getting hold of help collections etc when you sit behind an Http proxy&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;In that post we provided a solution which involved leveraging Fiddler’s ability to chain together proxy authentication on an application’s behalf.&lt;/p&gt;  &lt;p&gt;We also spotted &lt;a title="Another user on MSDN forums has a problem with MSDN Help behind a proxy" href="http://social.msdn.microsoft.com/Forums/en-US/setupprerelease/thread/a12a4ff0-add0-451f-a299-d45520f47db4/" target="_blank"&gt;this post on MSDN Forums&lt;/a&gt; and posted an answer indicating a possible solution for the person who opened the issue.&lt;/p&gt;  &lt;p&gt;As you’ll notice from the bottom post – a request was made by an employee of Microsoft to see if we could help them test a fix that they had in mind.&amp;#160; We did; the fix didn’t work completely, but we were then able to diagnose exactly why the fix didn’t work and have subsequently discovered how to make the Beta 2 MSDN 2010 Help Library Manager &lt;em&gt;without&lt;/em&gt; having to use Fiddler.&amp;#160; Based on our investigation, the team at Microsoft are now working on a fix – and might already have applied it in the &lt;a href="http://reddevnews.com/articles/2010/02/09/microsoft-releases-vs2010-rc.aspx" target="_blank"&gt;Release Candidate of VS2010 – which released in the last week&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Use at your own risk!&lt;/h2&gt;  &lt;p&gt;Before we go into the details, it must be stressed that this fix is not offered officially by Microsoft and therefore carries no guarantees from them.&amp;#160; We also make no guarantees about this fix either – it will involve changing registry settings and if this turns out to break anything else on your machine, then we will accept no responsibility for that.&amp;#160; It’s your choice to follow our directions here!&lt;/p&gt;  &lt;h3&gt;Step 1&lt;/h3&gt;  &lt;p&gt;Modify the HelpLibManager.exe.config file found in &lt;font color="#008000"&gt;Program Files &lt;em&gt;[&lt;strong&gt;(x86)&lt;/strong&gt; if on a 64 bit box]&lt;/em&gt;\Microsoft Help\v3.0&lt;/font&gt; and add the following xml inside the &amp;lt;configuration /&amp;gt; node:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.net&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;defaultProxy&lt;/span&gt; &lt;span style="color: #ff0000"&gt;useDefaultCredentials&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;defaultProxy&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.net&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Save the config file.&lt;/p&gt;

&lt;p&gt;On its own, this fix allows the help manager to ‘see’ the collections that are available for download – but it does not actually fix the problem of the download itself.&lt;/p&gt;

&lt;h3&gt;Step 2&lt;/h3&gt;

&lt;p&gt;This is the messy bit.&amp;#160; &lt;/p&gt;

&lt;p&gt;Open up the Registry Editor and make sure that registry value &lt;strong&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\BITS\UseLMCompat &lt;/strong&gt;is set to zero (the reason why is explained in a moment).&amp;#160; If you need to change it, you should make a note of the previous value – or better yet, create a System Restore Point.&lt;/p&gt;

&lt;p&gt;Restart the Background Intelligent Transfer Service, and then start up the help library manager.&amp;#160; It should all now work without any problems – assuming you have internet connectivity at all; and that your user name and password allow you through the proxy in the first place :)&lt;/p&gt;

&lt;h2&gt;Why does it work?&lt;/h2&gt;

&lt;p&gt;We ‘discovered’ that Help Library Manager uses &lt;a title="MSDN Topic on BITS" href="http://msdn.microsoft.com/en-us/library/aa362708(VS.85).aspx" target="_blank"&gt;BITS (Background Intelligent Transfer Service)&lt;/a&gt; to initiate and manage the actual downloads of the content.&amp;#160; Presumably this is because the files are typically rather large.&amp;#160; This runs in a separate process and is communicated with over a COM interface, therefore the configuration file fix has no effect on that.&lt;/p&gt;

&lt;p&gt;After some poking and prodding, we discovered that when a BITS transfer is initiated, &lt;a title="MSDN topic on Authentication with BITS transfers" href="http://msdn.microsoft.com/en-us/library/aa362781(VS.85).aspx" target="_blank"&gt;the caller has the opportunity to specify the credentials to be used for the network connection&lt;/a&gt;.&amp;#160; Working on the basis that the code in the Help Library can’t be setting these credentials (otherwise it would work), we looked for a way to get BITS to use default credentials.&amp;#160; The article from the last link above provides the answer to that – which yields the registry hack.&lt;/p&gt;

&lt;p&gt;Be aware that modifying this registry value affects all software that uses BITS – and therefore it’s just possible that other things might stop working as a result.&lt;/p&gt;

&lt;p&gt;As we mentioned earlier – we don’t know if the bug has been redressed in the RC of Visual Studio 2010 – our findings, including this fix, were submitted to Microsoft on the 27th January – so it’s possible it was too late.&lt;/p&gt;

&lt;p&gt;Hopefully, however, it’ll be fixed by the final release date!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;That’s it for now, but stay tuned: We have some very exciting news on the way in the next couple of weeks; but we’re not allowed to talk about it yet ;)&lt;/p&gt;</content></entry><entry><id>71ecacda-735f-4597-a3ca-4e928b134f25</id><title type="text">Link Tag in Content Control not created as HtmlLink</title><updated>2009-11-25T12:31:46Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Link-Tag-in-Content-Control-not-created-as-HtmlLink"/><category term="Technical"/><content type="html">&lt;p&gt;The Asp.Net &lt;a title="MSDN Topic about the HtmlHead class" href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlhead.aspx" target="_blank"&gt;System.Web.UI.WebControls.HtmlHead&lt;/a&gt; class is clever, especially when it comes to stylesheet &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tags in master pages, since it &lt;a title="Asp Alliance article about Url Rebasing in Asp.Net 2.0" href="http://aspalliance.com/1852_Url_Rebasing_in_ASPNET_20.1" target="_blank"&gt;magically rebases them&lt;/a&gt; (using &lt;a title="MSDN topic on Control.ResolveClientUrl" href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.resolveclienturl.aspx" target="_blank"&gt;Control.ResolveClientUrl&lt;/a&gt;) to be relative to the path of the page that is executing instead of the master page.&amp;#160; This is especially necessary when a content page is declared in a different folder to its master page, because any CSS references are unlikely to work except by pure fluke.&lt;/p&gt;  &lt;p&gt;With the advent of Visual Studio 2008, it has become common practise to have a content placeholder in a master page’s head section, which allows the page designer to add extra meta data, script references and CSS links on a content page as well.&amp;#160; To be fair, this process started almost as soon as master pages came into being – except &lt;a title="K Scott Allen shows how to use a content control in the Head section back in 2006" href="http://odetocode.com/Blogs/scott/archive/2006/04/11/the-contentplaceholder-not-just-for-content.aspx" target="_blank"&gt;Visual Studio 2005 did not have design-time support for it, a deficit that was much bemoaned by K. Scott Allen at the time&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This website uses that ability so that our master page contains our common CSS references, but some of our content pages then have their own script references and styles.&amp;#160; In order to get around the url-rebasing issue, we use a &lt;strong&gt;&amp;lt;base /&amp;gt;&lt;/strong&gt; tag at the top of every page, so that we can use root-relative links for our urls, css and javascript references, then the browser will happily get them from the correct place.&amp;#160; &lt;a title="Our most recent site bug fix" href="http://www.labs.jobserve.com/Articles.aspx/Website-update-16th-October-2009" target="_blank"&gt;A recent article detailing a fix for a small bug with the Atom Feed link&lt;/a&gt; on one of our pages details this process a bit more.&lt;/p&gt;  &lt;p&gt;Now we’re working on a new site, that will be using the &lt;a title="The Official ASP.Net site" href="http://www.asp.net/mVC/" target="_blank"&gt;Asp.Net MVC 1.0 Framework&lt;/a&gt; (and possibly 2.0 if it goes live before we’re finished).&amp;#160; This brings even more potential problems with relative URL links, since every page URL is actually a folder.&amp;#160; Although the &lt;strong&gt;&amp;lt;base/&amp;gt;&lt;/strong&gt; tag is a solution, it’s not perfect since you then have to define a way to actually format out that base url.&amp;#160; Many people use configuration, but it royally sucks for this, as it means that every time you move the site to a different machine (different developer boxes, QA box, staging box etc) or from a virtual directory to a website, you have to update the configuration.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Magic URL rebasing – the good&lt;/h2&gt;  &lt;p&gt;As mentioned in the introduction, any &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tag that is placed &lt;strong&gt;&lt;em&gt;directly inside&lt;/em&gt;&lt;/strong&gt; the Head control of an Asp.Net page will be turned into an &lt;a title="HtmlLink Declarative Syntax on MSDN" href="http://msdn.microsoft.com/en-us/library/ms228307.aspx" target="_blank"&gt;HtmlLink control&lt;/a&gt; – the magic for this is done in the &lt;a title="HtmlHeadBuilder control on MSDN" href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlheadbuilder.aspx" target="_blank"&gt;HtmlHeadBuilder&lt;/a&gt;’s &lt;a title="The GetChildControlType method of HtmlHeadBuilder" href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlheadbuilder.getchildcontroltype.aspx" target="_blank"&gt;GetChildControlType method&lt;/a&gt;: &lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Type GetChildControlType(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; tagName, IDictionary attribs)
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(tagName, &amp;quot;&lt;span style="color: #8b0000"&gt;title&lt;/span&gt;&amp;quot;, StringComparison.OrdinalIgnoreCase))
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HtmlTitle);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(tagName, &amp;quot;&lt;span style="color: #8b0000"&gt;link&lt;/span&gt;&amp;quot;, StringComparison.OrdinalIgnoreCase))
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HtmlLink);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(tagName, &amp;quot;&lt;span style="color: #8b0000"&gt;meta&lt;/span&gt;&amp;quot;, StringComparison.OrdinalIgnoreCase))
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HtmlMeta);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Very simple indeed.&amp;#160; As you can see, in order to get an HtmlLink created in place of a standard &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tag within the head, you have to do, well, nothing at all (not even make it &lt;strong&gt;runat=server&lt;/strong&gt;).&amp;#160; When the HtmlLink control renders it’s output, instead of dumbly rendering the attributes (i.e. the &lt;strong&gt;href&lt;/strong&gt;, &lt;strong&gt;rel&lt;/strong&gt; etc) it does this: &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RenderAttributes(HtmlTextWriter writer)
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Href))
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.Attributes[&amp;quot;&lt;span style="color: #8b0000"&gt;href&lt;/span&gt;&amp;quot;] = &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ResolveClientUrl(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Href);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.RenderAttributes(writer);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;a title="Control.ResolveClientUrl on MSDN" href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.resolveclienturl.aspx" target="_blank"&gt;ResolveClientUrl&lt;/a&gt; method is used to calculate the actual relative path to a resource, given a template-relative path (e.g. “&lt;em&gt;~/Pages/page.aspx&lt;/em&gt;”, “&lt;em&gt;~/Controls/control.ascx&lt;/em&gt;”, a master page virtual path or whatever) – which is retrieved from the first control up the parent-child hierarchy of the page that has one of these paths.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Magic URL rebasing – the bad&lt;/h2&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;&amp;lt;script&amp;gt; tags don’t get rebased - ever&lt;/h3&gt;

&lt;p&gt;There is one tag in particular that is missing from the logic in the above code - “script”.&amp;#160; Yes, that’s right, whilst &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tags will be magically rebased, &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; references will not – which is indeed a stark omission from the Asp.Net framework.&amp;#160; From the master page point of view, this means that you cannot really have &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; references in your master page’s header, unless all content pages will be in the same relative location from the target javascript file.&lt;/p&gt;

&lt;p&gt;This problem can be solved in a couple of different ways.&amp;#160; The first would be to pre-process the page content before it finally gets rendered, searching for any &lt;strong&gt;&amp;lt;script&amp;gt; &lt;/strong&gt;references, parsing them manually, using Control.ResolveClientUrl to get the target script reference and then writing the fixed URL back to the content (indeed, this approach has been taken with a fix adopted by one frustrated Asp.Net user; see later).&lt;/p&gt;

&lt;p&gt;However, the other approach is to write a simple server-side control to do it:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// Mimics the HtmlLink control - i.e. calling ResolveClientUrl at render time - &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// except it's done on the 'src' attribute value.  Since HtmlLink writes the resolved&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// path back to it's Href member, this one does the same.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; HtmlScript : HtmlGenericControl
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HtmlScript() : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(&amp;quot;&lt;span style="color: #8b0000"&gt;script&lt;/span&gt;&amp;quot;)
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HtmlScript(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; tag) : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(tag)
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Src
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Attributes[&amp;quot;&lt;span style="color: #8b0000"&gt;src&lt;/span&gt;&amp;quot;];
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Attributes[&amp;quot;&lt;span style="color: #8b0000"&gt;src&lt;/span&gt;&amp;quot;] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RenderAttributes(HtmlTextWriter writer)
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    Src = ResolveClientUrl(Src);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.RenderAttributes(writer);
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;With this in place, you simply use the &lt;strong&gt;&amp;lt;#@ Register &lt;/strong&gt;directive, or register a site-wide prefix via the web.config, to bring in a tag-prefix (e.g. “asp2”) for the control and then, in your ASPX source you change your &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; to:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp2&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;HtmlScript&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;../myscript.js&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;language&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;javascript&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp2&lt;/span&gt;:HtmlScript&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Okay, so this isn’t a perfect solution – a site-wide refactoring like this could take some time!&amp;#160; However, the best it yet to come…&lt;/p&gt;

&lt;h3&gt;Content controls in the head – even &amp;lt;link&amp;gt;s don’t get rebased&lt;/h3&gt;

&lt;p&gt;This is possibly the biggest problem, when you use a content control to inject extra links, references or whatever into a page head section from a content form, the magic CSS &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; rebasing no longer works.&amp;#160; Why?&amp;#160; The clue is in the above code snippet from HtmlHeadBuilder.GetChildControlType.&amp;#160; Consider the following master page, and content page:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Master Page &amp;lt;head&amp;gt; section: &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ContentPlaceHolder&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;TitleContent&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;link&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;../../Content/Site.css&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;ContentPlaceHolder&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;CustomHeadContent&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Content Page Content Placeholder: &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Content&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;customHead&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ContentPlaceHolderID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;CustomHeadContent&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;link&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;../../Content/Site.css&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Okay, so in this example, both pages are referencing the same stylesheet, so it’s slightly contrived.&amp;#160; However, assuming that the css files are in &lt;strong&gt;&lt;em&gt;~/Content/&lt;/em&gt;&lt;/strong&gt;, the master page is in the &lt;strong&gt;&lt;em&gt;~/pages/masters/&lt;/em&gt;&lt;/strong&gt; folder, and the content page is in the &lt;strong&gt;&lt;em&gt;~/pages/content/&lt;/em&gt;&lt;/strong&gt; folder, this will work fine when it is run.&lt;/p&gt;

&lt;p&gt;However, if we’re using something like MVC (or using the &lt;a title="HttpRequest.PathInfo - useful for creating beautified urls" href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.pathinfo.aspx" target="_blank"&gt;HttpRequest.PathInfo property&lt;/a&gt; like we do for our articles, projects etc) in order to beautify your urls, then we will run into problems.&amp;#160; For example, if the content page in question is actually displayed in the browser with the url “&lt;strong&gt;&lt;em&gt;/home/&lt;/em&gt;&lt;/strong&gt;”, then the CSS link rendered from the head on the master page will correctly come out as “&lt;strong&gt;&lt;em&gt;../content/site.css&lt;/em&gt;&lt;/strong&gt;”, however the CSS link from the page’s content control will be left untouched (indeed it will be rendered as a literal), and will generate a 404 when it hits the browser.&lt;/p&gt;

&lt;p&gt;This is because in order for the &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; markup in the content control to be turned into an HtmlLink, instead of being left as raw markup, the control builder that parses the &lt;strong&gt;&amp;lt;asp:Content&amp;gt;&lt;/strong&gt; control (ContentBuilderInternal – no MSDN link because it’s understandably undocumented!) would have to have the same logic in it that the head section does – since the ASP.Net build engine sees the &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tag as a child of the Content Control, not the HtmlHead that the content eventually gets merged into.&lt;/p&gt;

&lt;p&gt;This is clearly a bug, or at the very least an oversight, in the Asp.Net framework – and has been reported on &lt;a title="ContentPlaceHolder inside the Head Element bug on Connect" href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273683#tabs" target="_blank"&gt;MS Connect by Nathanael Jones&lt;/a&gt;, who came up with the &lt;a title="A solution to inconsistent url rebasing" href="http://nathanaeljones.com/146/referencing-stylesheets-scripts-from-content-pages/" target="_blank"&gt;aforementioned page-parsing solution on his blog&lt;/a&gt;.&amp;#160; However, this solution does not fix design-time problems (since the VS designer doesn’t run all of the page code when rendering it in the designer), and it is also quite a weighty solution which will inevitably slow down page rendering; our sites get tens of thousands of hits per day, and adding extra load on the servers is just not an option.&lt;/p&gt;

&lt;h2&gt;Our solution&lt;/h2&gt;

&lt;p&gt;Our solution fixes rebasing of all css &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tags in the head of content pages, and it also automatically picks up and rebases all &lt;strong&gt;&amp;lt;script&amp;gt; &lt;/strong&gt;references as well.&amp;#160; You’ll need the HtmlScript control, whose source code was presented earlier on; then add this code:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// It's a placeholder, really - it simply tells the framework to use the RebasingContainerBuilder to &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// create the controls that will emit the html.  Then, the designer is set to ControlDesigner - &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// the same one that the ContentControl uses.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// That ensures design-time support for the CSS and Javascript links on content pages.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[ControlBuilder(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(RebasingContainerBuilder)), 
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  Designer(&amp;quot;&lt;span style="color: #8b0000"&gt;System.Web.UI.Design.ControlDesigner, System.Design, &lt;/span&gt;&amp;quot; + 
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &amp;quot;&lt;span style="color: #8b0000"&gt;Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&lt;/span&gt;&amp;quot;), 
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  ConstructorNeedsTag(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; RebasingContainer : HtmlGenericControl
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; RebasingContainer()
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RenderBeginTag(System.Web.UI.HtmlTextWriter writer)
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {  &lt;span style="color: #008000"&gt;/*doesn't render it's own tag*/&lt;/span&gt; }
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RenderEndTag(System.Web.UI.HtmlTextWriter writer)
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {&lt;span style="color: #008000"&gt;/*doesn't render it's own tag*/&lt;/span&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// This class is almost identical to HtmlHeadBuilder.  It's purpose to ensure that embedded&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// links and script tags are always rebased for the client during rendering.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// The HtmlHead control does this for CSS link tags only, and the functionality is lost &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// on content controls on content forms.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// This builder is used by the &amp;lt;see cref=&amp;quot;RebasingContainer&amp;quot;/&amp;gt; control&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; RebasingContainerBuilder : ControlBuilder
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; AllowWhitespaceLiterals()
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Type GetChildControlType(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; tagName, System.Collections.IDictionary attribs)
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;/* copied this code from System.Web.UI.HtmlControls.HtmlHeadBuilder */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(tagName, &amp;quot;&lt;span style="color: #8b0000"&gt;link&lt;/span&gt;&amp;quot;, StringComparison.OrdinalIgnoreCase))
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HtmlLink);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(tagName, &amp;quot;&lt;span style="color: #8b0000"&gt;script&lt;/span&gt;&amp;quot;, StringComparison.OrdinalIgnoreCase) 
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &amp;amp;&amp;amp; attribs.Contains(&amp;quot;&lt;span style="color: #8b0000"&gt;src&lt;/span&gt;&amp;quot;))
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #008000"&gt;//only rebase script tags that have a src attribute!&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HtmlScript);
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;If you’ve placed this code inside the same assembly and namespace as the aforementioned HtmlScript class, then register a tag-prefix for that assembly/namespace (as before – the best place is in the web.config so it’s available on all pages) and you can start using it.&lt;/p&gt;

&lt;p&gt;In order for content page script and css references to get rebased you simply change this:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Content&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;indexCustomHead&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ContentPlaceHolderID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;CustomHeadContent&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;link&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/Content/TestSite.css&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/Content/script.js&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;language&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;javascript&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;To this:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #e1f8ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Content&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;indexCustomHead&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ContentPlaceHolderID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;CustomHeadContent&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp2&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;RebasingContainer&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;link&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/Content/TestSite.css&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/Content/script.js&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;language&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;javascript&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp2&lt;/span&gt;:RebasingContainer&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ecfeff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note that the asp2: prefix here depends on what prefix you actually register with Asp.Net.&amp;#160; At run-time and design time, the RebasingContainer control doesn’t render it’s own tags – it simply acts as a placeholder to instruct Asp.Net to delegate to RebasingContainerBuilder which, in turn, contains the logic to map &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; and &lt;strong&gt;&amp;lt;script&amp;gt; &lt;/strong&gt;tags to the server side controls that will perform the magic rebasing – just like the HtmlHead control.&lt;/p&gt;

&lt;p&gt;Similarly, you can use the rebasing container to rebase &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; tags in the master page’s &lt;strong&gt;&amp;lt;head&amp;gt;&lt;/strong&gt; content (or indeed any page’s head content) – simply move all your existing script tags into a new RebasingContainer, and it will work (don’t worry about the &amp;lt;link&amp;gt; tags – since the HtmlHeadBuilder will take care of those for you).&lt;/p&gt;

&lt;p&gt;When you first do this, the designer might get upset and tell you that it doesn’t recognise the RebasingContainer – simply do a full build, and it will update.&amp;#160; Now flip to design view on one of your content pages that previously didn’t work and smile at the fact that any extra stylesheets are now working in design view!&amp;#160; Notice also that inline javascript will pick up intellisense from any script references that have had to be rebased in order to be picked up.&lt;/p&gt;

&lt;h2&gt;A better, but near-impossible, solution&lt;/h2&gt;

&lt;p&gt;One solution that has been suggested by the community is to sub-class HtmlHead and it’s HtmlHeadBuilder in order to force &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; tags to be always mapped to HtmlLink controls.&amp;#160; There are numerous problems with this, the first and most crucial is that HtmlHead is a sealed class, so that’s impossible.&amp;#160; Even it were possible, however, it wouldn’t really help because, as explained earlier, the HtmlHeadBuilder is only used to parse the direct content of a runat=”server” &lt;strong&gt;&amp;lt;head&amp;gt; &lt;/strong&gt;control, and would never actually get a chance to process the ASPX markup for a page’s Content control.&lt;/p&gt;

&lt;p&gt;Another solution that we researched was to do a similar thing, but for the Content control; that is, sub-class the Content control and it’s associated control builder class, making it &lt;strong&gt;&amp;lt;link&amp;gt;&lt;/strong&gt; and &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; aware.&amp;#160; This would have meant simply changing the control tag used on a content page to inject content in the page’s header.&amp;#160; The big problem with this, however, is that the Content control uses an control builder that’s internal to Asp.Net: ContentBuilderInternal, which by definition cannot be subclassed.&amp;#160; It’s possible to call into internal classes and methods (using dynamic code generation – e.g. via Linq Expression Trees or DynamicMethod), but we didn’t have the time to build a proxy and all the code generation logic.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In the meantime, we hope that this explains the problem and provides you with an easy-to-use solution!&lt;/p&gt;</content></entry><entry><id>33779f6c-10bc-4d9e-8cfb-319e1a04174f</id><title type="text">VS2010 Beta 2 – Fatal Error Occurred installing Help</title><updated>2009-11-13T17:14:35Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/VS2010-Beta-2--Fatal-Error-Occurred-installing-Help"/><category term="Technical"/><content type="html">&lt;p&gt;&lt;font color="#008000"&gt;&lt;strong&gt;Update (10th Feb 2010)&lt;/strong&gt; – a more thorough investigation of this issue has been carried out by us (after being asked to help Microsoft fix the problem) and&lt;/font&gt; &lt;a href="http://www.labs.jobserve.com/Articles.aspx/We-help-Microsoft-fix-Visual-2010-Help-Manager"&gt;a new fix is detailed here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We’ve been playing around with the &lt;a title="Visual 2010 Beta 2 - get it now - free download from Microsoft" href="http://www.microsoft.com/visualstudio/en-gb/products/2010/default.mspx" target="_blank"&gt;beta 2 of Visual Studio 2010&lt;/a&gt; and really like the Web Install idea - although the actual VS2010 part of the download appears to be throttled at around 4Kb, which is a little frustrating!&lt;/p&gt;  &lt;p&gt;At the very end of the installation you get to install the new MSDN Help 3 Collections, choosing online or local help as your primary source.&amp;#160; If you’re running behind a web proxy that requires authentication you will see a “fatal error occurred” message pop up, and that’s it – there’s nothing you can do to get help on to your machine (except to get your SysAdmin to allow you out of the building without going through the proxy).&lt;/p&gt;  &lt;p&gt;However, we have found a rather cheeky solution to this problem – &lt;a href="http://www.fiddler2.com" target="_blank"&gt;the rather marvellous Fiddler Http Web Debugging Proxy&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;To get it to work&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Scenario 1:&lt;/em&gt;&lt;/strong&gt; All you should have to do is download Fiddler, install it and run it, then hit the ‘Get Content Online’ link again.&amp;#160; Eventually you’ll see all the content offerings, select the ones that you want and then hit the Update button.&lt;/p&gt;  &lt;p&gt;You should see web requests in Fiddler going through to packages.mtps.microsoft.com once the transfer starts.&amp;#160; Don’t worry if they appear to take for ages to complete – you’re watching a multi-part download, and nothing really interesting is going to happen until it’s finished!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Scenario 2:&lt;/em&gt;&lt;/strong&gt; If this doesn’t work – then it’s possible you might have to force Fiddler to remember your credentials for your proxy.&amp;#160; The best way to do this is to load a page in IE, and you should see a proxy login box appear.&amp;#160; Enter the correct credentials for your proxy and check that the web page then loads correctly.&lt;/p&gt;  &lt;p&gt;Now try to get the help content again – it should work.&lt;/p&gt;  &lt;h2&gt;Why does Fiddler make it work?&lt;/h2&gt;  &lt;p&gt;Here’s our theory: Obviously the Help installer client is not proxy-aware.&amp;#160; So it attempts to make a connection to the package download location, but hits the system proxy.&amp;#160; When this happens, the proxy returns a request for credentials, but the code isn’t written to send them over, and so it simply crashes.&lt;/p&gt;  &lt;p&gt;The reason why fiddler makes it work is because if it receives a Proxy Authentication request (Http Status Code 407) from the upstream proxy, it responds with the identity of the user running Fiddler (Scenario 1), or a token that has previously been known to work for the current session (Scenario 2).&amp;#160; &lt;/p&gt;  &lt;p&gt;If that isn’t good enough, it then pushes the 407 back to the client.&amp;#160; Now we already know that the Help Installer itself can’t cope with this, so in our Scenario 2 we use Internet Explorer to cheat, since it displays a login box when credentials are required.&lt;/p&gt;  &lt;p&gt;IE then sends those credentials to Fiddler, which in turn are then sent to your proxy – if the proxy then lets the request out, Fiddler will cache that authentication token to be used with &lt;strong&gt;&lt;em&gt;ALL&lt;/em&gt;&lt;/strong&gt; future requests (not just those coming from IE).&amp;#160; So when the Help Installer then makes another request, it signs that request as authenticated even though the Help Installer didn’t know it needed to.&lt;/p&gt;</content></entry><entry><id>94458b97-3268-4ab0-9822-650eb2c5ae81</id><title type="text">Remote debugging code on Windows 2003 from Vista or Windows 7/2008 R2</title><updated>2009-11-05T12:30:10Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Remote-debugging-code-on-Windows-2003-from-Vista-or-Windows-72008-R2"/><category term="Technical"/><content type="html">&lt;p&gt;We’re in the process of upgrading our development environment from Windows Server 2003 x64 to Windows Server 2008 R2.&amp;#160; Apart from the desktop experience being far superior, we’re also moving our web servers up to IIS 7.5, therefore we want all our web developers to be running the same.&amp;#160; Windows 7 is of course an option for this (and it works extremely well as a web development environment – unlike Windows XP Pro), however it doesn’t offer Hyper-V, which is a must for many developers who want to run their own database servers and mock web servers.&lt;/p&gt;  &lt;p&gt;Inevitably, however, we still have to support our existing codebase - all of which runs on Windows Server 2003.&amp;#160; Occasionally, therefore, we need to debug something that’s running live because a problem arises that is not easy to reproduce in a model office environment.&amp;#160; This typically means installing the Visual Studio Remote Debugger on the server that’s running the code and then attaching to it from the local Visual Studio.&amp;#160; Many people would say that this is bad practise; in our opinion bad practise is to go the whole hog and install Visual Studio on the server machine!&amp;#160; Remote debugging, on the other hand, is a reality of working as a developer in a technology-driven business.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;The problem&lt;/h2&gt;  &lt;p&gt;Today we had to do just this, but when we tried to connect to the remote machine we got the error message &amp;quot;a security package specific error occurred&amp;quot;.&amp;#160; If you &lt;a title="Google search for the remote debugger error" href="http://www.google.co.uk/search?hl=en&amp;amp;q=&amp;quot;a+security+package+specific+error+occurred&amp;quot;+remote+debugger&amp;amp;meta=" target="_blank"&gt;do a web search&lt;/a&gt; for this error, you’re likely to see &lt;a title="MSDN Forum link to &amp;quot;Remote Debugger Security Package Specific Error&amp;quot; question" href="http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/54f62bca-0d4b-4a64-82e2-ab6d60f859c9" target="_blank"&gt;this link from MSDN forums, where the user eventually solved the issue by creating a local user on both the target and local machines, and ran both VS2008 and the Remote Debugger as that account&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The solution presented is to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create two, administrator-level, identical local users on both the debugger machine and the debuggee machine &lt;/li&gt;    &lt;li&gt;Run the msvsmon.exe application (the Remote Debugger binary) as that local user on the debuggee &lt;/li&gt;    &lt;li&gt;Startup Visual Studio on the debugger machine as that local user &lt;/li&gt;    &lt;li&gt;Attach to the debuggee &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We weren’t happy with this resolution, because it points to a more fundamental problem – if Remote debugging works between two Windows 2008 R2 or Windows 7 machines, using the same VS binaries, why wouldn’t it work when talking to a Windows Server 2003 machine?&amp;#160; Equally, we don’t want to have to go around creating local users on developer machines and servers just to get remote debugging to work.&amp;#160; When you’ve reached this stage, it typically means that you’ve got an error you can’t reproduce any other way and you just need to ‘get it fixed quick’.&amp;#160; Also, in a TFS environment, the Visual Studio instance in which you’re doing the debugging will not be able to connect to TFS, because the local user that you’re using is unlikely to have access to source control etc.&lt;/p&gt;  &lt;p&gt;The root cause of this problem turns out to be slightly more subtle than the user on the aforementioned MSDN forum post assumed.&amp;#160; It is indeed authentication that is failing, but not the authentication of the user doing the debugging against the server they wish to debug.&amp;#160; In fact, after the remote debugging service receives a request to attach, &lt;a title="MSDN article describing a remote debugging error that sheds light on the authentication process" href="http://msdn.microsoft.com/en-us/library/ms164725.aspx" target="_blank"&gt;it then authenticates back to the machine that the request originates from&lt;/a&gt;&lt;em&gt;&lt;/em&gt;, and it is at this point that authentication is going wrong (we were able to generate the error that is described in that previous link by using a local account for the debugger service on the target machine but without creating it on the development machine).&lt;/p&gt;  &lt;p&gt;Even though our service was running as a domain account which has logon rights to the development machine, for some reason the NTLM network logon token for that account that is sent back by the debugging service would appear not to work properly.&lt;/p&gt;  &lt;p&gt;By enabling network level NTLM auditing (in Local Security Policy, enable the two settings “Network security: Restrict NTLM: Audit Incoming NTLM traffic” and “Network security: Restrict NTLM: Audit NTLM Authentication in this domain”) we were able to see the logon occur, but then the logon session is destroyed (presumably as a result of the “Security package specific error” that occurs).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;A (slightly) easier solution&lt;/h2&gt;  &lt;p&gt;The good news from this is that we can offer a streamlined solution to the one provided in the above MSDN link, the bad news is that you’ll still need to create the local users:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create the two users as before on the two machines – however, &lt;strong&gt;it only needs to be an administrator on the target machine&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;Modify the remote debugger service on the target machine to use the new local user, start the service. &lt;/li&gt;    &lt;li&gt;Run Visual Studio 2008 &lt;strong&gt;&lt;u&gt;as you would normally&lt;/u&gt;&lt;/strong&gt; (no need to run as the local user), and attach the debugger as normal. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Tell Microsoft!&lt;/h2&gt;  &lt;p&gt;&lt;a title="&amp;quot;A security package specific error occured&amp;quot; Visual Studio bug on Microsoft Connect" href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=508455" target="_blank"&gt;We have logged a bug on Microsoft Connect&lt;/a&gt; so that the VS team can investigate the issue – if you are affected by this issue then please vote for it!&amp;#160; At present we do not know if this also affects Visual Studio 2010 (we have a development lab set up and will investigate), if you can verify that it does, then add your experience to that bug so that we can ensure that at least the next version of VS isn’t plagued by this issue, even if it doesn’t get fixed in the current version.&lt;/p&gt;</content></entry><entry><id>23463497-fd9c-43a1-8fc4-69ba303fc851</id><title type="text">Website update 16th October 2009</title><updated>2009-10-16T13:57:00+01:00</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Website-update-16th-October-2009"/><category term="Technical"/><content type="html">&lt;p&gt;Firstly, our apologies to some of you over the past few days who’ve had problems accessing our site feed from your browsers’ RSS auto-discovery icon.&amp;#160; We’ve been catching some errors at this end where some of you have apparently been trying to access our feed url (&lt;a href="http://www.labs.jobserve.com/jslabs.svc/feed"&gt;http://www.labs.jobserve.com/jslabs.svc/feed&lt;/a&gt;) from one of our virtual sub-folders (such as the &lt;strong&gt;Articles.aspx&lt;/strong&gt; sub folder that you’ll see in your browsers address bar on this page).&lt;/p&gt;  &lt;p&gt;We’ve modified our master page now so that the feed url specified in the RSS &lt;strong&gt;&amp;lt;link /&amp;gt;&lt;/strong&gt; tag will always be correct – we hope this didn’t stop you from being able to access our site feed!&lt;/p&gt;  &lt;h2&gt;Why did it happen?&lt;/h2&gt;  &lt;p&gt;A lot of work has gone into this website at our end to make it easy for us to develop, test and deploy.&amp;#160; Part of this is ensuring that the site works as well under an IIS virtual directory (which is what developers usually do) as it does as its own IIS root website (when it’s deployed to our live servers).&lt;/p&gt;  &lt;p&gt;Usually you can use the ‘~/’ notation in Asp.Net to work around this problem; however a lot of our pages, although they are ASPX pages, do not use server-side controls and tags.&amp;#160; This is to keep the load on the webservers to a minimum, but it also means that we can’t always use virtual paths on our links, images and all the other stuff that makes up a web page.&lt;/p&gt;  &lt;p&gt;Throw into the mix that we’re using the &lt;a title="HttpRequest.PathInfo property on MSDN" href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.pathinfo.aspx" target="_blank"&gt;HttpRequest.PathInfo&lt;/a&gt; property on many of our pages (an idea garnered from &lt;a title="Scott Guthrie - URL Rewriting with Asp.Net" href="http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx" target="_blank"&gt;Scott Guthrie’s article on URL rewriting for SEO purposes&lt;/a&gt;) – which means that a lot of relative paths can no longer be taken for granted.&lt;/p&gt;  &lt;p&gt;For example – a &lt;strong&gt;&amp;lt;head&amp;gt;&lt;/strong&gt; link to &lt;strong&gt;styles/labs_base.css&lt;/strong&gt; works fine if the page in the browser is simply &lt;strong&gt;Articles.aspx&lt;/strong&gt; (since that’s in the root of the website), but since all articles are actually served from &lt;strong&gt;Articles.aspx&lt;em&gt;/[Article-Title]&lt;/em&gt;&lt;/strong&gt;, then your browser will incorrectly make a css request for &lt;strong&gt;Articles.aspx/styles/labs_base.css&lt;/strong&gt; – which, of course, doesn’t exist.&lt;/p&gt;  &lt;p&gt;A typical solution this problem would be to change the path in the master page to &lt;strong&gt;/styles/labs_base.css – &lt;/strong&gt;but this would break the site in development, unless we always enforce our developers to run their development site in a website in IIS (using the Cassini isn’t an option because there are a few other tricks being employed by this site which don’t work when running in that).&amp;#160; Equally we could make all our &lt;strong&gt;&amp;lt;link/&amp;gt;&lt;/strong&gt;s, &lt;strong&gt;&amp;lt;a href&lt;/strong&gt;s et al to be &lt;strong&gt;runat=”server”&lt;/strong&gt; – but that’s making the web server do more work than it really needs to.&lt;/p&gt;  &lt;p&gt;How do &lt;em&gt;we&lt;/em&gt; fix the problem, then?&amp;#160; We use a &lt;strong&gt;&amp;lt;base /&amp;gt;&lt;/strong&gt; tag, which is placed within the &lt;strong&gt;&amp;lt;head /&amp;gt;&lt;/strong&gt; section of every page – this tells your browser that all relative Urls start from a given location – in our case &lt;a href="http://www.labs.jobserve.com"&gt;www.labs.jobserve.com&lt;/a&gt; – which means that we can then use relative links everywhere for everything.&amp;#160; Our code for calculating the base Url is partly taken from the request’s Url, as well as the application path:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; BaseAddress
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//stick &amp;quot;http://&amp;quot; or &amp;quot;https://&amp;quot; in front of this as required&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;{0}{1}&lt;/span&gt;&amp;quot;,HttpContext.Current.Request.Url.Authority, 
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      HttpContext.Current.Request.ApplicationPath);
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This code works reliably regardless of whether or not the site is running in a virtual directory or under its own website; meaning that our development team can develop the site however they want and we can deploy the site however we want in the future.&lt;/p&gt;

&lt;p&gt;The original problem with our site feed link from the master page was that it was relative, i.e. &lt;strong&gt;jslabs.svc/feed&lt;/strong&gt;, but unfortunately it appears that some, if not all, browsers, were ignoring the &lt;strong&gt;&amp;lt;base /&amp;gt;&lt;/strong&gt; tag.&amp;#160; Now, our feed link is rendered absolute – including the &lt;strong&gt;http://&lt;/strong&gt; bit, and it should work on every page.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;So there you go – if you’re developing an Asp.Net website, then coding around base url of your site at deployment time and during development will be an inevitable problem.&amp;#160; You can take a brute force approach, force Website/Virtual Directory configuration to be the same from Development to Live – or you can find a more elegant approach that ultimately makes your code much more portable.&amp;#160; Ours is just one solution; there are many more floating around out there.&lt;/p&gt;

&lt;p&gt;If you were affected by this – we hope that you now enjoy unfaltering access to our site feed!&lt;/p&gt;</content></entry><entry><id>98d19438-5fa6-4a4c-ba3c-a7a1e49b40aa</id><title type="text">Building Labs – Writing an OpenSearch Suggestions provider in C# with WCF</title><updated>2009-08-17T16:50:53+01:00</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Building-Labs--Writing-an-OpenSearch-Suggestions-provider-in-C-with-WCF"/><category term="Technical"/><content type="html">&lt;p&gt;This is the second in a series of articles on how we’ve built JobServe Labs and some of &lt;a title="The JobServe Labs full project list" href="http://www.labs.jobserve.com/AllProjects.aspx" target="_blank"&gt;the projects that are available&lt;/a&gt;.&amp;#160; &lt;a title="Building Labs - XML RPC Backend for Windows Live Writer" href="http://www.labs.jobserve.com/Articles.aspx/Building-Labs--XML-RPC-Backend-for-Windows-Live-Writer-in-C-with-WCF" target="_blank"&gt;In the first article&lt;/a&gt; we described how we’re using &lt;a title="Download Page for Windows Live Writer" href="http://download.live.com/writer" target="_blank"&gt;Windows Live Writer&lt;/a&gt; to manage our content, and how we’ve written an XML RPC backend for it to talk to, using &lt;a title="The WCF Homepage on MSDN" href="http://msdn.microsoft.com/en-us/netframework/aa663324.aspx" target="_blank"&gt;WCF&lt;/a&gt; in C#.&lt;/p&gt;  &lt;p&gt;This time, we’re going to look at the suggestions service that we did for our &lt;a title="The JobServe Labs Search Provider Browser Plugin" href="http://www.labs.jobserve.com/Projects.aspx/Web-Browser-OpenSearch-Provider" target="_blank"&gt;Web Browser Search Provider&lt;/a&gt;, and how you can set up your own.&lt;/p&gt;  &lt;p&gt;Before you start reading, please feel free to &lt;a title="Get the source code now!" href="http://www.labs.jobserve.com/Files.aspx/OpenSearchDemo.zip" target="_blank"&gt;download the source code&lt;/a&gt; that is built by following this walkthrough – it also shows how to output the images in the suggestions that are supported by IE8.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;What is OpenSearch?&lt;/h2&gt;  &lt;p&gt;Originally, &lt;a title="OpenSearch Specification at OpenSearch.Org" href="http://www.opensearch.org/Home" target="_blank"&gt;OpenSearch&lt;/a&gt; enabled a website to expose to interested consumers (be they web browsers, search engines or anything else) any of the search capabilities that they might have.&amp;#160; The notion of extracting this out to a standard meant that a consumer could be automatically compatible with lots of search engines once the code had been written to interpret one.&lt;/p&gt;  &lt;p&gt;The search facility of a website typically takes the form of a URL that can accept a &lt;a title="W3Schools Reference on URL Encoding" href="http://www.w3schools.com/TAGS/ref_urlencode.asp" target="_blank"&gt;URL-encoded&lt;/a&gt; search phrase in the query string – for example, many people will be familiar with Google’s query string format, since each search results page is represented by a different URL:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.google.co.uk/search?hl=en&amp;amp;q=jobserve" href="http://www.google.co.uk/search?hl=en&amp;amp;q=jobserve" target="_blank"&gt;http://www.google.co.uk/search?hl=en&amp;amp;q=jobserve&lt;/a&gt; – first page of a Google Search for ‘jobserve’&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.google.co.uk/search?q=jobserve&amp;amp;hl=en&amp;amp;start=10&amp;amp;sa=N" href="http://www.google.co.uk/search?q=jobserve&amp;amp;hl=en&amp;amp;start=10&amp;amp;sa=N" target="_blank"&gt;http://www.google.co.uk/search?q=jobserve&amp;amp;hl=en&amp;amp;start=10&amp;amp;sa=N&lt;/a&gt; – second page – note the additional ‘start’ parameter, which tells the search engine which result should come first.&lt;/p&gt;  &lt;p&gt;If you’re looking to implement OpenSearch for your website, then you should, at a minimum, have a URL that can also ‘seed’ a search in this way.&lt;/p&gt;  &lt;p&gt;The interactive suggestions-part of OpenSearch is an extension that was suggested after the original spec was drawn up, and is, primarily, a convenient way that a search service can help users narrow down their search without having to first run multiple searches.&amp;#160; For example, a lookup into a known keywords list, a list of popular searches, both of these, or more besides.&lt;/p&gt;  &lt;p&gt;Our search suggestions service, for example, responds with actual job results which (in IE8 only, unfortunately) take you directly to the job page.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Before you start&lt;/h2&gt;  &lt;p&gt;Assuming you do have a URL on your site that you can use to launch your search – you should then take a look at the &lt;a title="OpenSearch Specification at OpenSearch.Org" href="http://www.opensearch.org/Home" target="_blank"&gt;OpenSearch&lt;/a&gt; spec, which is the standard around which your suggestions service is going to be built, and which is one of the easier to understand standards.&amp;#160; In particular, you should review the &lt;a title="OpenSearch Specification - Suggestions" href="http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0" target="_blank"&gt;OpenSearch Suggestions Extension&lt;/a&gt; specification, which details the URL format that your service should ideally support and format of the data that you should be returning.&amp;#160; One thing to note here is that the specification describes the response data you should return in terms of JSON-formatted objects; however this is not your only option.&amp;#160; Microsoft have adapted and &lt;a title="XML Search Suggestions Format Specification - for IE8" href="http://msdn.microsoft.com/en-us/library/cc848863(VS.85).aspx" target="_blank"&gt;extended the OpenSearch Suggestions Extension into XML format for use with Internet Explorer 8&lt;/a&gt;, and with this you have additional capabilities in IE8, such as separators and images in your suggestions list:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="msie8_extendedsearchsuggestions" border="0" alt="msie8_extendedsearchsuggestions" src="http://www.labs.jobserve.com/files.aspx/msie8extendedsearchsuggestions38a4f890-64c5-4230-a0fc-b14a1ad6aea8.jpg" width="332" height="343" /&gt; &lt;/p&gt;  &lt;p&gt;In the above screenshot, you can see the top result has an associated image, and the search service is also using a separator to embed a link to an information page about Microsoft’s newly branded Bing search engine.&lt;/p&gt;  &lt;p&gt;When it comes to the choice between the JSON or XML suggestions format, you don’t necessarily have to chose either/or – IE8 supports both, whereas Firefox, for example, only supports the JSON format.&amp;#160; However you can expose two services in one OpenSearch Description Document, and both browsers can hang off the one document quite happily (IE8 will favour the XML service when faced with both).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Project Setup&lt;/h2&gt;  &lt;p&gt;We use Visual Studio 2008 here, so these steps are based on you using that environment.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create a new C# Asp.Net Web Application &lt;/li&gt;    &lt;li&gt;Leave the project’s web properties so that it runs from the Visual Studio Development Web Server – it’s considerably easier to do testing with this - however you will want to manually specify the port so that later on your code knows the base location of the URLs to be generated. &lt;/li&gt;    &lt;li&gt;Now add a new WCF service – call it ‘OpenSearch.svc’ (&lt;em&gt;&lt;strong&gt;Hint: &lt;/strong&gt;the ‘WCF Service’ item template is found in the ‘C#’ root folder on the add dialog&lt;/em&gt;). &lt;/li&gt;    &lt;li&gt;When you create WCF services, the wizard automatically modifies the web.config to add WS-HTTP and Metadata Exchange (MEX) endpoints – you can remove these from the configuration as we’re going to be working with the &lt;a title="WebServiceHostFactory in the MSDN Library" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.webservicehostfactory.aspx" target="_blank"&gt;zero-configuration WebServiceHostFactory&lt;/a&gt; which is great for creating RESTful services for XML and JSON. &lt;/li&gt;    &lt;li&gt;Also, the wizard abstracts the service implementation from it’s operation contracts by creating an interface, IOpenSearch in this case – which you can delete. &lt;/li&gt;    &lt;li&gt;Open the code-behind for the service (OpenSearch.svc.cs) and remove the IOpenSearch interface from the class, and get rid of the ‘DoWork’ method declaration from the class body. &lt;/li&gt;    &lt;li&gt;Finally, you need to add a reference to the System.ServiceModel.Web assembly – this brings in the aforementioned WebServiceHostFactory class, as well as the WebGetAttribute and UriTemplate classes, which we need in order to expose our service on the URLs of our choice. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Results Classes&lt;/h2&gt;  &lt;p&gt;In order to support both the JSON OpenSearch suggestions format (supported by Firefox) and XML OpenSearch suggestions format (used by Internet Explorer 8), we unfortunately have to split our class definitions between the two uses.&amp;#160; This is because the JSON format is based on a &lt;a title="Description of Parallel Arrays on Wikipedia" href="http://en.wikipedia.org/wiki/Parallel_array" target="_blank"&gt;parallel array approach&lt;/a&gt;, with the Completions, Descriptions and QueryURLs being specified in three separate arrays, whereas the XML format is object-oriented, with all three pieces of data being specified as child values of a common suggestion element.&lt;/p&gt;  &lt;p&gt;These two approaches can’t easily be represented in one set of classes for WCF serialization purposes, so to solve this problem in the way most convenient for us, our primary result classes on the server are going to be the ones that’ll produce the XML results for IE8 (to provide class-&amp;gt;entity mapping for the XML), and we’ll create another standalone class for our JSON result format that can be constructed from those.&lt;/p&gt;  &lt;p&gt;The first type you need is for each individual suggestion itself:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[DataContract(Namespace = &amp;quot;&lt;span style="color: #8b0000"&gt;http://schemas.microsoft.com/Search/2008/suggestions&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Suggestion
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [DataMember(EmitDefaultValue = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Url { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [DataMember]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Text { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [DataMember(EmitDefaultValue = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Description { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [DataMember(Name = &amp;quot;&lt;span style="color: #8b0000"&gt;Image&lt;/span&gt;&amp;quot;, EmitDefaultValue = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; SuggestionImage Image { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The keen eye will notice that we’ve also got a dependency on the ‘SuggestionImage’ class, which should be specified as follows:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SuggestionImage : IXmlSerializable
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Source { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Alt { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Height { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Width { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; XmlSchema GetSchema()
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ReadXml(XmlReader reader)
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//we never actually load our results from XML&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; WriteXml(XmlWriter writer)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    writer.WriteAttributeString(&amp;quot;&lt;span style="color: #8b0000"&gt;source&lt;/span&gt;&amp;quot;, Source);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    writer.WriteAttributeString(&amp;quot;&lt;span style="color: #8b0000"&gt;alt&lt;/span&gt;&amp;quot;, Alt);
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(Height.ToString()) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      writer.WriteAttributeString(&amp;quot;&lt;span style="color: #8b0000"&gt;height&lt;/span&gt;&amp;quot;, Height.ToString());
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(Width.ToString()) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      writer.WriteAttributeString(&amp;quot;&lt;span style="color: #8b0000"&gt;width&lt;/span&gt;&amp;quot;, Width.ToString());
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This class might seem a little odd – since it doesn’t use any DataContract or DataMember attribute declarations.&amp;#160; The reason for this is because the XML OpenSearch format requires that the image data is specified in XML attributes; this requirement is initially a total show-stopper, because the WCF DataContractSerializer doesn’t natively support XML attribute serialization via its attributes.&amp;#160; However, &lt;a title="How to serialize to attributes with the DataContractSerializer in WCF" href="http://lordzoltan.blogspot.com/2010/09/serializing-to-attributes-in-wcf-with.html" target="_blank"&gt;you can take over the XML serialization yourself and write attribute strings&lt;/a&gt; for a given type if you simply implement the IXmlSerializable interface.&lt;/p&gt;

&lt;p&gt;Now, we need to define the outer types in which we’re going to place our suggestions.&amp;#160; If you take a look at &lt;a title="IE8 XML Search Suggestions Format" href="http://msdn.microsoft.com/en-us/library/cc848863(VS.85).aspx" target="_blank"&gt;the aforementioned XML suggestions format&lt;/a&gt;, you’ll see that a root-node is expected, called ‘SearchSuggestion’, inside which we have an element called ‘Query’, and then one called ‘Section’, inside which each of our suggestion items should be written.&amp;#160; In order to achieve the latter correctly, we have to use the &lt;a title="CollectionDataContractAttribute on the MSDN Library" href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.collectiondatacontractattribute.aspx" target="_blank"&gt;CollectionDataContract&lt;/a&gt; attribute, which allows us to define the inner element that’ll go within the &amp;lt;Section/&amp;gt; element, and give our list the name ‘Section’ at the same time:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[CollectionDataContract(Name = &amp;quot;&lt;span style="color: #8b0000"&gt;Section&lt;/span&gt;&amp;quot;, 
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;   Namespace = &amp;quot;&lt;span style="color: #8b0000"&gt;http://schemas.microsoft.com/Search/2008/suggestions&lt;/span&gt;&amp;quot;, 
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;   ItemName = &amp;quot;&lt;span style="color: #8b0000"&gt;Item&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SuggestionsSection : List&amp;lt;Suggestion&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Note the use of the List&amp;lt;&amp;gt; generic here.&lt;/p&gt;

&lt;p&gt;And then, finally, we define our outermost result, that our search suggestions service is actually going to return to our callers:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[DataContract(Name = &amp;quot;&lt;span style="color: #8b0000"&gt;SearchSuggestion&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  Namespace = &amp;quot;&lt;span style="color: #8b0000"&gt;http://schemas.microsoft.com/Search/2008/suggestions&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Suggestions
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [DataMember]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Query { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [DataMember]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; SuggestionsSection Section { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;One of the things that might be confusing about all our [DataContract] classes here is that we repeatedly specify the namespace.&amp;#160; We have to do this, otherwise the DataContractSerializer will, (un)helpfully take our class’ namespace and use that.&amp;#160; Being XML, the namespace is very important, and IE8 will refuse to parse the XML results you throw back if there are errant namespaces in your returned data.&amp;#160; By specifying the same namespace on every class, the DataContractSerializer will only output the namespace on the root node, as it will be satisfied that no namespace changes occur as it drills down through the data that it serializes.&lt;/p&gt;

&lt;p&gt;We don’t have to worry about this on our SuggestionImage class, because it is our responsibility to write the namespace attribute out - because we’ve implemented IXmlSerializable – as a result, we simply don’t bother.&lt;/p&gt;

&lt;h3&gt;Adding support for the Separator element&lt;/h3&gt;

&lt;p&gt;You will notice that we’re not supporting the &amp;lt;Separator /&amp;gt; element of the XML format - this oversight is for brevity in this article.&amp;#160; If you wanted to support this you would need to introduce a common interface, ‘ISuggestionItem’, which the Suggestion object could implement.&amp;#160; Then you’d introduce another class, called ‘SuggestionSeparator’, which also implements the same interface.&amp;#160; Note here that to support titles on your Separators you’d also need to implement IXmlSerializable again, because the title is expected to be an attribute and, as we saw with the SuggestionImage class, we have to take over serialization when we want to do this.&lt;/p&gt;

&lt;p&gt;Finally, you’d change your declaration of the SuggestionsSection class so that it inherits from List&amp;lt;ISuggestionItem&amp;gt;, and add two [&lt;a title="Known Types in DataContracts - MSDN library" href="http://msdn.microsoft.com/en-us/library/ms730167.aspx" target="_blank"&gt;KnownType&lt;/a&gt;] attribute declarations to that class so as to support Suggestion and SuggestionSeparator.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;Moving on to the JSON Result object&lt;/h2&gt;

&lt;p&gt;As previously mentioned – and &lt;a title="OpenSearch Suggestion Extension specification" href="http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0" target="_blank"&gt;as is outlined in the aforementioned specification&lt;/a&gt; – the JSON results format is, curiously, not a structure, but an array of arrays.&amp;#160; This poses an interesting problem for the DataContractSerializer, because it’s JSON capabilities, provided by the &lt;a title="DataContractJsonSerializer class on MSDN" href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx" target="_blank"&gt;DataContractJsonSerializer&lt;/a&gt;, are geared to produce JSON structures with fields mapped to the properties of the .Net type being serialized.&amp;#160; The answer?&amp;#160; To have your JSON object masquerade as a JSON array, and to add what you would normally think of as fields to that array on construction:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[KnownType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;))]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[KnownType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]))]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; JSONSuggestions : List&amp;lt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Query;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] Completions;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] Descriptions;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] QueryURLs;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; JSONSuggestions() { &lt;span style="color: #008000"&gt;/*default Ctor required by WCF*/&lt;/span&gt; }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; JSONSuggestions(Suggestions source)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//build the individual members&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    Query = source.Query;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    Completions = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[source.Section.Count];
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    Descriptions = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[source.Section.Count];
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    QueryURLs = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[source.Section.Count];
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; current = 0;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var result &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; source.Section)
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Completions[current] = result.Text;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      QueryURLs[current] = result.Url;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Descriptions[current] = result.Description;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      ++current;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//then add them to the inner list of objects in the &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//order that the JSON suggestions format decrees.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Add(Query);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Add(Completions);
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Add(Descriptions);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Add(QueryURLs);
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Note that we’re not using the DataContract/DataMember attributes on this class – instead we’re simply leveraging &lt;a title="Aaron Skonnard&amp;#39;s blog - POCO support in .Net 3.5 SP1" href="http://www.pluralsight.com/community/blogs/aaron/archive/2008/05/13/50934.aspx" target="_blank"&gt;WCF’s POCO support introduced in .Net 3.5 SP1&lt;/a&gt;.&amp;#160; The solution presented by this class is quite subtle, and worthy of study.&amp;#160; First, the class inherits from List&amp;lt;object&amp;gt; – this is because we need to be able to serialize both a string (for the ‘query’ data) and arrays of strings (for the completions, descriptions and URLs data).&amp;#160; As a result, we also have to lend the DataContractSerializer a helping hand by using the KnownType attribute, so that it knows in advance that the list could contain either of these two types.&lt;/p&gt;

&lt;p&gt;Our only constructor takes in our Suggestions object that we’ve prototyped in the previous section, and simply leeches all the data out of it into temporary holding variables.&amp;#160; Finally, these holding variables are added to the list in the order that the OpenSearch suggestions format specifies.&amp;#160; When this object is serialized by the JSON serializer, it will be written out as an array, because the outermost type is a collection type.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;The Query Page and the Search Service&lt;/h2&gt;

&lt;p&gt;Now, we’re not going to write an actual &lt;em&gt;search&lt;/em&gt; service here – what you’ll be left with is the skeleton code in which you can easily plug your search engine code.&amp;#160; We’re going to focus instead on the sprint finish to getting something returned to your browser.&amp;#160; We also need a few pages in our website project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A search page that accepts a query string search parameter, as explained in the opening section &lt;/li&gt;

  &lt;li&gt;A few additional pages that we can present as actual search results &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our demo service is going to be query-string agnostic; so, although it will accept a query string, the results it returns are not going to be influenced by that input string – that’s for you to do.&amp;#160; The final step after this is to craft our OpenSearch description document so that web browsers can pick up our search provider.&lt;/p&gt;

&lt;p&gt;So, quickly:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add three content pages to your web project – we’re going to call ours ‘Result1.aspx’, ‘Result2.aspx’ and ’Result3.aspx’.&amp;#160; Put some basic content on there that you can use to discriminate the three from each other. &lt;/li&gt;

  &lt;li&gt;Add another page, and call it ‘Search.aspx’.&amp;#160; Modify the code-behind as follows: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Search : System.Web.UI.Page
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _searchPhrase;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SearchPhrase
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(_searchPhrase == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Request.QueryString.Count == 0 ||
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;          (_searchPhrase = Request.QueryString[&amp;quot;&lt;span style="color: #8b0000"&gt;q&lt;/span&gt;&amp;quot;]) == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;          _searchPhrase = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _searchPhrase;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Now, open the mark-up for the page, and replace the body with:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      You searched for '&lt;span style="background-color: #ffff00; color: black"&gt;&amp;lt;%&lt;/span&gt;= SearchPhrase &lt;span style="background-color: #ffff00; color: black"&gt;%&amp;gt;&lt;/span&gt;'&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    Results:&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ul&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;li&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Result1.aspx&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Result 1&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        The first result page
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;li&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;li&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Result2.aspx&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Result 2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        The second result page
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;li&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;li&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Result3.aspx&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Result 3&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;        The third result page
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;li&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ul&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;With all that in place, it’s now time to go back to our OpenSearch.svc and expose our XML and JSON endpoints.&lt;/p&gt;

&lt;p&gt;The first step is to open the .svc mark-up itself and add the highlighted code to it, to enable the WebServiceHostFactory:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&amp;lt;%@ ServiceHost Language=&amp;quot;&lt;span style="color: #8b0000"&gt;C#&lt;/span&gt;&amp;quot; Debug=&amp;quot;&lt;span style="color: #8b0000"&gt;true&lt;/span&gt;&amp;quot; Service=&amp;quot;&lt;span style="color: #8b0000"&gt;OpenSearchDemo.OpenSearch&lt;/span&gt;&amp;quot; CodeBehind=&amp;quot;&lt;span style="color: #8b0000"&gt;OpenSearch.svc.cs&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;Factory=&amp;quot;&lt;span style="color: #8b0000"&gt;System.ServiceModel.Activation.WebServiceHostFactory&lt;/span&gt;&amp;quot; 
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;%&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Now we open the code-behind file and write our two service methods – one for XML and one for JSON:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[ServiceContract()]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; OpenSearch
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [OperationContract]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [WebGet(UriTemplate = &amp;quot;&lt;span style="color: #8b0000"&gt;suggestions?q={query}&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    RequestFormat = WebMessageFormat.Xml,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    ResponseFormat = WebMessageFormat.Xml)]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Suggestions GetSuggestions(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//TODO: replace with your real search engine code.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    Suggestions toReturn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Suggestions() 
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      { Query = query, Section = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SuggestionsSection() };
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//for brevity, we've fixed our dev web server's port so that we know exactly where&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//these URLs need to point.  In reality you'll either use auto-discovery by taking&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #008000"&gt;//a look at the WCF WebOperationContext, or via a configuration file.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    toReturn.Section.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Suggestion()
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Description = &amp;quot;&lt;span style="color: #8b0000"&gt;Result 1 Description&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Text = &amp;quot;&lt;span style="color: #8b0000"&gt;Result 1&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Url = &amp;quot;&lt;span style="color: #8b0000"&gt;http://localhost:37082/Result1.aspx&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    });
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    toReturn.Section.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Suggestion()
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Description = &amp;quot;&lt;span style="color: #8b0000"&gt;Result 2 Description&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Text = &amp;quot;&lt;span style="color: #8b0000"&gt;Result 2&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Url = &amp;quot;&lt;span style="color: #8b0000"&gt;http://localhost:37082/Result2.aspx&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    });
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    toReturn.Section.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Suggestion()
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Description = &amp;quot;&lt;span style="color: #8b0000"&gt;Result 3 Description&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Text = &amp;quot;&lt;span style="color: #8b0000"&gt;Result 3&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;      Url = &amp;quot;&lt;span style="color: #8b0000"&gt;http://localhost:37082/Result3.aspx&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    });
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; toReturn;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [OperationContract]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  [WebGet(UriTemplate = &amp;quot;&lt;span style="color: #8b0000"&gt;json/suggestions?q={query}&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    RequestFormat = WebMessageFormat.Json,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    ResponseFormat = WebMessageFormat.Json)]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; JSONSuggestions GetJSONSuggestions(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  {
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; JSONSuggestions(GetSuggestions(query));
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  }
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note how the implementation of the JSON service is simply a piggy-back off the XML one.&amp;#160; When you’re writing XML and JSON services in this way, typically all the code will either go in one half of the implementation, or in another common block of code that both can call.&amp;#160; The contents of the WebGet attribute are very important at this point – and you should familiarise yourself with &lt;a title="Aaron Skonnard on MSDN: RESTFul services in WCF 3.5" href="http://msdn.microsoft.com/en-us/library/dd203052.aspx#" target="_blank"&gt;RESTful programming in WCF&lt;/a&gt; if you’re going to be writing more of these kinds of services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE: In the downloadable source code, we’ve included the ‘Image’ property for each of these results, so you can see the attribute-based image data in action as well.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Testing the services&lt;/h2&gt;

&lt;p&gt;At this point you should be able to build and run without any errors.&amp;#160; Once done, you should be able to open the url &lt;strong&gt;&lt;em&gt;http://localhost[:devwebport]/suggestions.svc?q=Hello+World&lt;/em&gt;&lt;/strong&gt; and, although you might not actually see any output in the browser, if you open the source for the current page you’ll see the XML response in the format the IE8 will be expecting.&lt;/p&gt;

&lt;p&gt;Also, if you instead open &lt;strong&gt;&lt;em&gt;http://localhost[:devwebport]/json/suggestions.svc?q=Hello+World&lt;/em&gt;&lt;/strong&gt;, you should be prompted to initiate a file download which, when you open it in notepad, will be a JSON array of arrays as per the actual OpenSearch suggestions spec.&lt;/p&gt;

&lt;p&gt;If in doubt, use &lt;a title="Fiddler2 Web Debugging Proxy" href="http://fiddler2.com/fiddler2/" target="_blank"&gt;Fiddler2&lt;/a&gt; to debug the web traffic.&amp;#160; Note that you cannot get other people to call this yet, if you’re using the development web server that is, because it only responds to requests from the local machine.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Writing the OpenSearch Description document&lt;/h2&gt;

&lt;p&gt;Again, we’re not giving a full description of the OpenSearch spec here – everything you need to do is available from the OpenSearch site, we’re just giving you the XML you need to get up and running.&amp;#160; Add a new XML file to your web project, call it OpenSearch.xml, paste this in after the &amp;lt;?xml&amp;gt; directive:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;OpenSearchDescription&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://a9.com/-/spec/opensearch/1.1/&amp;quot;&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;                       &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;moz&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://www.mozilla.org/2006/browser/search&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ShortName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;JSLabs OpenSearchDemo&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ShortName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Expose OpenSearch on your Website, with suggestions!&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;InputEncoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;UTF-8&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;InputEncoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;&amp;lt;!-- used by all opensearch compatible browsers --&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Url&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;template&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://localhost:37082/search.aspx?q={searchTerms}&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;method&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Get&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;&amp;lt;!-- suggestions - used by IE8 only --&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Url&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;application/x-suggestions+xml&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;template&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://localhost:37082/opensearch.svc/suggestions?q={searchTerms}&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;method&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Get&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;&amp;lt;!-- suggestions - used by Firefox --&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Url&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;application/x-suggestions+json&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;template&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://localhost:37082/opensearch.svc/json/suggestions?q={searchTerms}&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;method&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Get&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;&amp;lt;!-- best practise to include a link to self --&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Url&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;application/opensearchdescription+xml&amp;quot;&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;self&amp;quot;&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;       &lt;span style="color: #ff0000"&gt;template&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://lostlhost:37082/opensearch.xml&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;&amp;lt;!-- not required, but another extension supported by Firefox --&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;moz&lt;/span&gt;:&lt;span style="color: #800000"&gt;SearchForm&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;http://localhost:37082&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;moz&lt;/span&gt;:&lt;span style="color: #800000"&gt;SearchForm&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;OpenSearchDescription&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Final Step – Wiring the OpenSearch document up for the browser&lt;/h2&gt;

&lt;p&gt;&lt;a title="Search provider extensibility in IE" href="http://msdn.microsoft.com/en-us/library/cc848862(VS.85).aspx#spe_addprov" target="_blank"&gt;As this excellent article on MSDN describes&lt;/a&gt; – there are a few ways to promote your OpenSearch provider.&amp;#160; One is auto-discovery, which is the recommended standards-based way to do it, and is supported by both IE7/8 and Mozilla Firefox 2/3.&amp;#160; To enable auto-discovery for our demo site, open up your Search.aspx page, and add this to the &amp;lt;head&amp;gt; region:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;link&lt;/span&gt; &lt;span style="color: #ff0000"&gt;title&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;JSLabs OpenSearch Demo Provider&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;search&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;   &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;application/opensearchdescription+xml&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;   &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://localhost:37082/opensearch.xml&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Save the mark-up – and now, open IE 7/8.&amp;#160; Browse to /Search.aspx (no query string required) – and you’ll see the quick search box change colour:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="building-labs-opensearch-ie8-add-1" border="0" alt="building-labs-opensearch-ie8-add-1" src="http://www.labs.jobserve.com/files.aspx/building-labs-opensearch-ie8-add-148a41a68-2ad3-41f0-bd63-e89d0c27c32c.jpg" width="314" height="68" /&gt; &lt;/p&gt;

&lt;p&gt;Click on the down-arrow and expand the ‘Add Search Providers’ pop-out menu.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="building-labs-opensearch-ie8-add-2" border="0" alt="building-labs-opensearch-ie8-add-2" src="http://www.labs.jobserve.com/files.aspx/building-labs-opensearch-ie8-add-2933921bf-9b39-4400-b8f7-0219e83a16d8.jpg" width="524" height="233" /&gt;&lt;/p&gt;

&lt;p&gt;Confirm the dialog box that comes up (in IE8 make sure that the ‘Use suggestions from this provider’ box is ticked).&amp;#160; Once done, expand the list again, and select the newly added ‘JSLabs OpenSearch Demo’ provider (there’ll be two very similar, it’s the one with the magnifying glass) and start typing, you should see your three suggestions appear:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="building-labs-opensearch-ie8-in-action" border="0" alt="building-labs-opensearch-ie8-in-action" src="http://www.labs.jobserve.com/files.aspx/building-labs-opensearch-ie8-in-action3c60ec00-618c-46fa-ac3b-92164058d5c3.jpg" width="347" height="225" /&gt; &lt;/p&gt;

&lt;p&gt;If you select either of the three results, notice that they take you straight through to the Result[1-3].aspx pages, rather than simply launch the search page again with that suggestion (this is how our Job Search suggestions end up taking you straight through to the job page).&lt;/p&gt;

&lt;p&gt;For Firefox, the process is nigh-on identical, browse to the page, the search box will highlight and you can select the provide from a dropdown list:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="building-labs-opensearch-ff3-add-1" border="0" alt="building-labs-opensearch-ff3-add-1" src="http://www.labs.jobserve.com/files.aspx/building-labs-opensearch-ff3-add-1bc34bb97-736b-4a3b-b8b8-7ea062fd71d8.jpg" width="375" height="349" /&gt; &lt;/p&gt;

&lt;p&gt;Again, you’ll be asked to confirm whether you want to use suggestions from this provider, which you do.&lt;/p&gt;

&lt;p&gt;At this point you can immediately start typing in the quick-search box, and our suggestions will appear:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="building-labs-opensearch-ff3-in-action" border="0" alt="building-labs-opensearch-ff3-in-action" src="http://www.labs.jobserve.com/files.aspx/building-labs-opensearch-ff3-in-action0ac3c569-ab98-46d9-bd8f-aaac19040cdc.jpg" width="324" height="146" /&gt; &lt;/p&gt;

&lt;p&gt;This is where Firefox is a bit of a let-down, however (and why our job search provider does not provide suggestions in Firefox), if you select any of these results, you’ll notice that instead of browsing directly to the URL we’re passed back in the results (like IE8), Firefox simply launches the search page with the string ‘Result 1’, ‘Result 2’ or ‘Result 3’ (it’s whichever Completion string is selected).&amp;#160; &lt;a title="OpenSearch bug in Firefox - Bug 386591" href="https://bugzilla.mozilla.org/show_bug.cgi?id=386591#c5" target="_blank"&gt;This is a bug in the Mozilla browser&lt;/a&gt;, and was raised quite a while ago – we await to see if it’ll be fixed.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The other way to get your provider added to a browser is to use the non-standard AddSearchProvider method of the window.external property – and have a hyperlink or button that users can click to add the provider manually to the browser:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;#&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;   &lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;window.external.AddSearchProvider('http://localhost:37082/opensearch.xml')&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;   &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Add JSLabs OpenSearch Demo provider&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This is the technique that we use for our &lt;a title="The JobServe OpenSearch provider" href="http://www.labs.jobserve.com/Projects.aspx/Web-Browser-OpenSearch-Provider" target="_blank"&gt;Web Browser OpenSearch Provider&lt;/a&gt;, primarily because we are hosting our provider on a different sub-domain to the main site.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a title="Launch article for Web Browser OpenSearch Provider" href="http://www.labs.jobserve.com/Articles.aspx/In-Browser-Search-Provider-Released" target="_blank"&gt;As is mentioned in the launch article&lt;/a&gt; for the Web Browser OpenSearch Provider, Chrome and Safari do not support OpenSearch.&amp;#160; Opera 9 should, according to the documentation, support the auto-discovery method of supplying OpenSearch to the web browser.&amp;#160; Support doesn’t just have to stop at the browser, though - remember that there are websites out there which could leverage your OpenSearch capability (not the suggestions, just the basic search url) in order to better your content to a wider audience.&amp;#160; All in all, installing OpenSearch into your website is a worthwhile effort – and with WCF, supporting the suggestions extension is surprisingly simple.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a title="Get the source code for this article" href="http://www.labs.jobserve.com/Files.aspx/OpenSearchDemo.zip" target="_blank"&gt;Download the source code for this article now!&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>7049ce77-6612-4748-b2f4-831fdd527f63</id><title type="text">Building Labs – XML RPC Backend for Windows Live Writer in C# with WCF</title><updated>2009-07-10T17:48:31+01:00</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Building-Labs--XML-RPC-Backend-for-Windows-Live-Writer-in-C-with-WCF"/><category term="Technical"/><content type="html">&lt;p&gt;In the first of our series of articles about how JobServe Labs is built, we’re going to look at how we’re using &lt;a title="Download Page for Windows Live Writer" href="http://download.live.com/writer" target="_blank"&gt;Windows Live Writer&lt;/a&gt; (WLW) to publish our articles, and how we’ve setup a blog service internally with &lt;a title="The WCF Homepage on MSDN" href="http://msdn.microsoft.com/en-us/netframework/aa663324.aspx" target="_blank"&gt;WCF&lt;/a&gt; for WLW to talk to.&amp;#160; If you’re planning a similar deployment, or if you’re looking for a way to build page-based content management for a website, then you might want to read through – as we point you in the direction of how to build it yourself.&lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;Why use Windows Live Writer?&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;We needed to be able to create rich content with the minimum of fuss, with the ability to embed content such as video, pictures etc only a few clicks away.&amp;#160; While there are ready-made javascript-based HTML editors out there (&lt;a title="The TinyMCE project homepage" href="http://tinymce.moxiecode.com/" target="_blank"&gt;TinyMCE&lt;/a&gt; and &lt;a title="The FCKEditor homepage" href="http://www.fckeditor.net/" target="_blank"&gt;FCKEditor&lt;/a&gt; are two excellent and very popular examples) we tend to find that non-technical users don’t get on with them too well – many people will copy and paste from word processing applications, but inevitably the resulting content is messy and doesn’t translate to the web page very well. &lt;/li&gt;    &lt;li&gt;Writing our own WYSIWYG X-Html editor, whilst not impossible, would have taken far too long. &lt;/li&gt;    &lt;li&gt;With WLW, users get a recognisable interface on which they will require minimal training (a real consideration in an enterprise environment). &lt;/li&gt;    &lt;li&gt;We &lt;a title="The Windows Live Writer SDK Homepage" href="http://msdn.microsoft.com/en-us/library/aa738906.aspx" target="_blank"&gt;can extend WLW through it’s very slim and easy to use plugin APIs&lt;/a&gt;, all you need as a developer is to install it, and you have the SDK. &lt;/li&gt;    &lt;li&gt;We’re already using WLW to post to our own internal blogs, which are hosted on &lt;a title="The MOSS homepage at Microsoft" href="http://sharepoint.microsoft.com/Pages/Default.aspx" target="_blank"&gt;Microsoft Office Sharepoint&lt;/a&gt;, and many of our colleagues are already using this, so all we’re really doing for these guys is adding an additional information outlet for them to post to in an environment they already understand. &lt;/li&gt;    &lt;li&gt;WLW already knows how to talk to many popular blogging engines such as &lt;a title="The Wordpress Homepage" href="http://wordpress.org/" target="_blank"&gt;Wordpress&lt;/a&gt;, &lt;a title="The Blogger homepage" href="https://www.blogger.com/start" target="_blank"&gt;Blogger&lt;/a&gt; and &lt;a title="MetaWebLog RFC on XMLRPC.com" href="http://www.xmlrpc.com/metaWeblogApi" target="_blank"&gt;MetaWebLog&lt;/a&gt;-based engines such as &lt;a title="BlogEngine.Net - the .Net Blogging Engine" href="http://www.dotnetblogengine.net/" target="_blank"&gt;BlogEngine.Net&lt;/a&gt;.&amp;#160; One of our developers is already using it blog to his own personal blog, and we therefore we knew that some of our expectations could be achieved so long as we stuck to a recognised standard. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;The architecture&lt;/h2&gt;  &lt;p&gt;Unlike other out-of-the-box blogging sites/engines, you will not find our blog endpoint on our website.&amp;#160; The primary reason for doing this was to minimise attack vectors to the site – if you present a callable endpoint to the outside world then somebody will try to hack it.&amp;#160; Anybody that could ever want to interact with the articles on our site will either be directly on our enterprise network, or connected to it remotely via a VPN.&lt;/p&gt;  &lt;p&gt;The basic architecture, then, is:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Labs Blog Architecture" border="0" alt="Labs Blog Architecture" src="http://www.labs.jobserve.com/files.aspx/Labs-Blog-Architecture3.png" width="501" height="907" /&gt; &lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Blog capabilities&lt;/h2&gt;  &lt;p&gt;The first stage was for us to decide which common blog functionality we wanted to support on our blog, and from there we could then determine which Blog spec we would code against.&amp;#160; Using the &lt;a title="Defining Weblog Capabilities using the Options element in wlwmanifest.xml" href="http://msdn.microsoft.com/en-us/library/bb463260.aspx" target="_blank"&gt;Windows Live Writer default capabilities listings&lt;/a&gt;, we decided that we would use the MetaWebLog specification as our baseline, as it’s the closest to what we wanted.&amp;#160; There were a couple of additional features we wanted to add, but these can be done using the &amp;lt;options&amp;gt; element of the wlwmanifest.xml file that our website presents to Live Writer – for those who are interested, here’s the complete listing from ours:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;options&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;clientType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Metaweblog&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;clientType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPostAsDraft&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPostAsDraft&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsFileUpload&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsFileUpload&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsCustomDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsCustomDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsCommentPolicy&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsCommentPolicy&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsExcerpt&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsExcerpt&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsNewCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsNewCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsNewCategoriesInline&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsNewCategoriesInline&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsMultipleCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsMultipleCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsHierarchicalCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsHierarchicalCategories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsKeywords&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsKeywords&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPingPolicy&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPingPolicy&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsAuthor&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsAuthor&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsSlug&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsSlug&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPassword&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPassword&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsTrackbacks&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsTrackbacks&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPages&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPages&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPageParent&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPageParent&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPageOrder&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsPageOrder&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;&amp;lt;!--additional live writer options--&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsEmptyTitles&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsEmptyTitles&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;requiresHtmlTitles&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;requiresHtmlTitles&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;requiresXHTML&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;requiresXHTML&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsScripts&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsScripts&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsEmbeds&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsEmbeds&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;characterSet&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;UTF-8&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;characterSet&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;maxCategoryNameLength&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;40&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;maxCategoryNameLength&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsAutoUpdate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;supportsAutoUpdate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;options&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;If you’ve had any experience customising Live Writer from the manifest file, you might be wondering why we are specifying values that are the same as the defaults for the MetaWebLog spec.&amp;#160; Part of it is to ensure that if Live Writer’s understanding of this spec changes in a future version, it’s understanding of our blog will not.&amp;#160; It’s also to make it easier in the future should we wish to add capabilities – changing an existing value from No to Yes is simply faster than having to write the element in first.&lt;/p&gt;

&lt;p&gt;An important point to note, if you’re going to develop your own blog engine like this, is that &lt;a title="Relationship between MetaWeblog and Blogger APIs on XMLRPC.com" href="http://www.xmlrpc.com/metaWeblogApi#relationshipBetweenMetaweblogApiAndTheBloggerApi" target="_blank"&gt;the MetaWebLog specification implies the Blogger specification&lt;/a&gt; as well, and WLW mixes it’s XML RPC calls between the two for the different features where the MetaWebLog RPC methods supersede the Blogger methods.&lt;/p&gt;

&lt;p&gt;As an example, it will use the &lt;strong&gt;&lt;em&gt;metaWeblog.editPost&lt;/em&gt;&lt;/strong&gt; method instead of the &lt;strong&gt;&lt;em&gt;blogger.editPost&lt;/em&gt;&lt;/strong&gt; method when you re-publish an existing post; but it will use the &lt;strong&gt;&lt;em&gt;blogger.deletePost&lt;/em&gt;&lt;/strong&gt; method to delete a post because MetaWebLog doesn’t define an alternative method for doing so.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;XML RPC&lt;/h2&gt;

&lt;p&gt;The next step was to decide how we were going to expose the blog to Live Writer – which is expecting an XML RPC endpoint to talk to.&amp;#160; There is a &lt;a title="The XML-RPC.Net homepage" href="http://www.xml-rpc.net/" target="_blank"&gt;very popular .Net Framework implementation of XML RPC, called XML-RPC.net&lt;/a&gt;, which we did look at, however we are moving all of our network coding over to WCF because your code is then not tied to a particular transport or protocol.&lt;/p&gt;

&lt;p&gt;The problem with that is that WCF does not come with built-in message formatters and operation selectors compatible with XML RPC; so we were looking at writing our own.&amp;#160; As we all know, however, as developers, we must always exhaust the community first to see if somebody else has done it, and to our joy we stumbled across a project by &lt;a title="About Clemens Vasters - on his MSDN Blogs site" href="http://blogs.msdn.com/clemensv/about.aspx" target="_blank"&gt;Clemens Vasters&lt;/a&gt; – a senior developer at Microsoft – where he’d been developing just such a thing for &lt;a title="The DasBlog site - blogging engine used by a lot of people!" href="http://www.dasblog.info/" target="_blank"&gt;DasBlog&lt;/a&gt;.&amp;#160; The zipped solution, &lt;a title="Clemens Vasters&amp;#39; final article and iteration of his excellent WCF XML RPC implementation" href="http://vasters.com/clemensv/PermaLink,guid,679ca50b-c907-4831-81c4-369ef7b85839.aspx" target="_blank"&gt;which he talks about and links to on his blog&lt;/a&gt;, includes WCF operation selectors and formatters for XML RPC support in the same way that you write any other WCF hosted service (i.e using the ServiceContract attribute and OperationContract attribute).&amp;#160; All we did was to take his ServiceHost setup code and move it to a core component that we could then host either in a console application (as in his example), which was great for development, or in a windows service for when we actually released it to the rest of the business.&lt;/p&gt;

&lt;p&gt;Helpfully, he also includes WCF-contracted interface definitions (and the corresponding classes for their related structs) for &lt;strong&gt;Blogger&lt;/strong&gt;, &lt;strong&gt;MetaWebLog&lt;/strong&gt; and &lt;strong&gt;MovableType&lt;/strong&gt;, as well as an in-memory implementation of his Blog Engine that runs from the command-line (which Live Writer will happily connect to).&amp;#160; We didn’t use these directly, but if you’re following the same path as us, then you can go straight ahead and do so.&amp;#160; Clemens stacks his interfaces up like this:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;//define the interface for the actual blog api that will be called&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[ServiceContract]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IBlogAPI : IMovableType
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;//define the interface for the IMovableType interface&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[ServiceContract(Namespace = &amp;quot;&lt;span style="color: #8b0000"&gt;http://www.sixapart.com/developers/xmlrpc/&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IMovableType : IMetaWeblog
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;//example&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	[OperationContract(Action = &amp;quot;&lt;span style="color: #8b0000"&gt;mt.setPostCategories&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; mt_setPostCategories(
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; postid,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; username,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; password,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		Category[] categories &lt;span style="color: #008000"&gt;/* MovableType category */&lt;/span&gt; );
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;// rest of the method definitions ommitted.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;//define the interface for the IMetaWebLog interface&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[ServiceContract(Namespace = &amp;quot;&lt;span style="color: #8b0000"&gt;http://www.xmlrpc.com/metaWeblogApi&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IMetaWeblog : IBlogger
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;//example&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	[OperationContract(Action=&amp;quot;&lt;span style="color: #8b0000"&gt;metaWeblog.editPost&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; metaweblog_editPost(
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; postid,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; username,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; password,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		Post post, &lt;span style="color: #008000"&gt;/* MetaWebLog post struct */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; publish);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;// rest of the method definitions ommitted.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;//finally, define the base interface for IBlogger - the base API used by all&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;[ServiceContract(Namespace = &amp;quot;&lt;span style="color: #8b0000"&gt;http://www.blogger.com/developers/api/1_docs/&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IBlogger
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;//example&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	[OperationContract(Action=&amp;quot;&lt;span style="color: #8b0000"&gt;blogger.deletePost&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; blogger_deletePost(
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; appKey,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; postid,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; username,
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; password,
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; publish);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;// rest of the method definitions ommitted.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;One of the challenges is that many of the specifications share ‘struct’ definitions that are called the same thing, but which are subtlely different.&amp;#160; The MetaWebLog Post struct, for example, is not the same as the Blogger Post struct.&amp;#160; Clemens’ code namespaces each of the above interfaces and the classes that they require according to the blog API they implement.&amp;#160; As a result, you will find yourself implementing some methods from different interfaces which use slightly different structs even if they have the same name.&amp;#160; Thankfully, Windows Live Writer will always send the right struct version for the particular method it’s calling!&lt;/p&gt;

&lt;p&gt;Now, to setup your real blog API, you simply declare a class that implements the root IBlogAPI (it’s actually IBloggerAPI in Clemens’ code – but that’s easy to confuse with the Blogger interface!), get Visual Studio to stub out all the interface methods you need, and then start coding against your database.&amp;#160; We used &lt;a title="Original MSDN Article about Linq to SQL" href="http://msdn.microsoft.com/en-us/library/bb425822.aspx" target="_blank"&gt;Linq to Sql&lt;/a&gt; for our database interfacing layer because it’s really quick to get up and running, and is resilient to schema changes; it’s also hack-proof.&amp;#160; &lt;a title="First part of Scott Gu&amp;#39;s Linq to Sql series" href="http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx" target="_blank"&gt;Read through Scott Gu’s excellent series on using Linq to Sql&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’re not going to go through hosting the service and the C# code required to do that – it’s all in Clemens’ project.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Bugfixes required to Microsoft.Samples.XmlRpc&lt;/h2&gt;

&lt;p&gt;During development, we discovered a couple of minor bugs in the XmlRpcDataContractSerializer class – which we had to patch for our use.&amp;#160; Unfortunately, we can’t make the amended version of the file available here as it’s got Microsoft’s Copyright on it, so we have sent our amendments to Clemens and hopefully he’ll patch the release that we’ve linked to above.&amp;#160; To patch it yourself, open up the file XmlRpcDataContractSerializer.cs and make the following changes:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;/* -----------------------------------------------------------------
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Change 1: Line 65, adding else statement to if block that starts
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * if (dataMembers.ContainsKey(memberName))&amp;quot; on line 44:
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Fixes: A crash that occurs if a struct field is sent that is
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * not part of the class being used to represent the struct in .Net
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * -----------------------------------------------------------------*/&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	reader.Skip();
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;reader.ReadEndElement(); &lt;span style="color: #008000"&gt;// value&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;reader.MoveToContent();
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;reader.ReadEndElement(); &lt;span style="color: #008000"&gt;// member&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;reader.MoveToContent();
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;/*-------------------------------------------------------------------*/&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;/* ------------------------------------------------------------------
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Change 2: Line 128, Replace case statement which deserialises
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * an XmlRpc DateTime value
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Fixes: Crash when parsing DateTime values passed by Windows Live
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Writer when setting an explicit publish date on an article.  
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * XML RPC date format is not a .Net date time format.
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * ------------------------------------------------------------------*/&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;case&lt;/span&gt; XmlRpcProtocol.DateTime:
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  returnValue = Convert.ChangeType(reader.ReadElementContentAsDateTime(), targetType);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; dateTime = reader.Value;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;//have to fix the current reader position (dirty fix).&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  reader.Read();
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  reader.Read();
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  reader.Read();
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  returnValue = XmlConvert.ToDateTime(dateTime, &amp;quot;&lt;span style="color: #8b0000"&gt;yyyyMMddTHH:mm:ss&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;/*-------------------------------------------------------------------*/&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;/* ------------------------------------------------------------------
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Change 3: Line 249, replace the else-if
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * Fixes: This is the mirror fix to change 2 - ensures that outgoing
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * DateTimes are formatted correctly.
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt; * ------------------------------------------------------------------*/&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (valueType == &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(DateTime))
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  writer.WriteStartElement(XmlRpcProtocol.DateTime);
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #008000"&gt;//modification here to write a 'proper' Xml RPC DateTime.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;value&lt;/span&gt; &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime)
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    writer.WriteValue(((DateTime)&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;).ToString(&amp;quot;&lt;span style="color: #8b0000"&gt;yyyyMMddTHH:mm:ss&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;    writer.WriteValue(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;  writer.WriteEndElement();
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #008000"&gt;/*-------------------------------------------------------------------*/&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Layout and Preview modes for WLW&lt;/h2&gt;

&lt;p&gt;So now we have our blog service ready to go (assuming you’ve done your database and your XML RPC Endpoints are setup) the last thing we have to do is to tell Live Writer where our blog is, and what our pages look like.&lt;/p&gt;

&lt;p&gt;Before you begin this bit, you should have a website that can display your blog posts – at a minimum this must have a root page which shows either all posts, or the most recent &lt;em&gt;n&lt;/em&gt; posts – the top post should be the one that was posted most recently.&amp;#160; Use this as your blog’s homepage from WLW’s point of view.&amp;#160; Ours is &lt;a title="Our all articles page - the homepage for our blog" href="http://www.labs.jobserve.com/AllArticles.aspx" target="_blank"&gt;our All Articles page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the best editing experience in WLW you should also have two additional Html Files, one for WebLayout view (editing view in WLW) and WebPreview view (the preview shown in WLW).&amp;#160; &lt;a title="Providing WebLayout and WebPreview views on MSDN" href="http://msdn.microsoft.com/en-us/library/bb463261.aspx" target="_blank"&gt;The Live Writer Team have written guidance on MSDN&lt;/a&gt; as to how to make these two files – they use placeholders for the title and the article body – so the most basic version of these would simply look like this:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; 
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;{post-title}&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	{post-body}
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Live Writer simply substitutes the {post-title} and {post-body} macros for the content that it’s got from the current post – if the page requests CSS or Image files, then WLW will go and download them.&lt;/p&gt;

&lt;p&gt;From our experience with this process, we also have a few suggestions and guidelines for you to follow regarding these files:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;WebLayout View&lt;/h3&gt;

&lt;p&gt;If your site has a graphical theme and funky layout (ours, for example uses a master page that puts the header and footer on, surrounds most content with a rounded border, and sticks a load of other links on), you’ll typically leave it off this page so as to maximise the default editing experience. &lt;/p&gt;

&lt;p&gt;For example, this article looks like this in my editing view: 
  &lt;br /&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="buildinglabs_xmlrpc_livewriter_editingview" border="0" alt="buildinglabs_xmlrpc_livewriter_editingview" src="http://www.labs.jobserve.com/files.aspx/buildinglabsxmlrpclivewritereditingview1.jpg" width="684" height="447" /&gt; &lt;/p&gt;

&lt;p&gt;Note how the title is much larger than it appears on this page, and how there are no borders anywhere.&amp;#160; The font and link styles, however, are maintained.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;WebPreview View&lt;/h3&gt;

&lt;p&gt;This one should be as close to the design used for the page that displays a single article (in this case the page that you’re looking at right now) – ours, for example is an aspx page that includes the master page and a lot of the extra HTML layout content.&lt;/p&gt;

&lt;p&gt;Because you’re likely to be throwing all manner of CSS tricks at this page, it’s possible that it’ll not be identical to the actual web page; my preview, for example, takes a few liberties with the placement of our Feeds and Categories panels on the right hand side (WLW does a good job of it’s HTML compliancy, but it’s not perfect).&amp;#160; However, the important thing is that it accurately displays the post inside the rounded panel surrounding the content:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="buildinglabs_xmlrpc_livewriter_previewview" border="0" alt="buildinglabs_xmlrpc_livewriter_previewview" src="http://www.labs.jobserve.com/files.aspx/buildinglabsxmlrpclivewriterpreviewview.jpg" width="684" height="447" /&gt;&lt;/p&gt;

&lt;h2&gt;The manifest file&lt;/h2&gt;

&lt;p&gt;Now that you have your preview and layout htmls, you can write your manifest file.&amp;#160; From the information that we’ve mentioned so far, you’ve almost got what you need to do it.&amp;#160; First, I’ll link again over to the &lt;a title="Everything you need to know about manifest files" href="http://msdn.microsoft.com/en-us/library/bb463266.aspx" target="_blank"&gt;Windows Live Writer Customisation API topic on MSDN&lt;/a&gt;, so you’ve got all the material to back you up.&lt;/p&gt;

&lt;p&gt;Let’s assume that you are going to implement MetaWebLog exactly as is, with no customisations.&amp;#160; Let’s also assume that your homepage is default.aspx, and that your WebLayout and WebPreview htmls are called ‘WebLayout.html’ and ‘WebPreview.html’.&amp;#160; Your manifest file is going to look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;span style="color: #0000ff"&gt;?&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;manifest&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://schemas.microsoft.com/wlw/manifest/weblog&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #008000"&gt;&amp;lt;!-- leave the options bit out, because we're sticking with what
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		live writer uses as the defaults for MetaWebLog --&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;weblog&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;My Blog&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;homepageLinkText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;http://my.domain.com/default.aspx&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;homepageLinkText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;weblog&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;views&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;default&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;WebLayout&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;default&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;view&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;WebPreview&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WebPreview.html&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;view&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;WebLayout&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WebLayout.html&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;views&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #eaf4ff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;manifest&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;As the MSDN documentation states, if you place this file in the root of your website and call it ‘wlwmanifest.xml’, then Windows Live Writer will be able to auto-detect it.&amp;#160; If, however, you need to point Live Writer specifically at a particular file (we actually have two Blog endpoints for our site, one for our Articles and one for our Projects, so we need two manifests), then you use a &amp;lt;link&amp;gt; tag in the &amp;lt;head&amp;gt; section of the blog’s homepage.&amp;#160; Here, it’s the ‘rel’ and ‘type’ attributes that do the magic:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #f2feff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 11px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;link&lt;/span&gt; &lt;span style="color: #ff0000"&gt;rel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;wlwmanifest&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;application/wlwmanifest+xml&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;MyWlwManifest.xml&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;With this in place, Windows Live Writer can auto-discover the manifest that you want it to use.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Final Step – Adding your Blog to Windows Live Writer&lt;/h2&gt;

&lt;p&gt;If you’re at this stage:&lt;/p&gt;

&lt;p&gt;1) You’ve got a website that has a manifest file for Live Writer to download as per the last section – let’s say that the address is&lt;strong&gt; http://localhost/default.aspx&lt;/strong&gt; for homepage. 

  &lt;br /&gt;2) You’ve got your blog API listening on an address on a local machine as per the section about Xml Rpc.&amp;#160; Let’s say that’s on &lt;strong&gt;http://localhost:9999/blog/api&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then you’re ready to go!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Go to the ‘Blogs’ menu of Live Writer and select the bottom option “Add Blog Account” &lt;/li&gt;

  &lt;li&gt;Select ‘Other Blog Service’ &lt;/li&gt;

  &lt;li&gt;Set the web address of the blog to http://localhost/default.aspx &lt;/li&gt;

  &lt;li&gt;If you’ve added permissions to your blog, then set the username and password.&amp;#160; Click next. &lt;/li&gt;

  &lt;li&gt;Now WLW wants to know what type of provider it’s going to be talking to – select “Metaweblog API” &lt;/li&gt;

  &lt;li&gt;In the address box type &lt;strong&gt;http://localhost:9999/blog/api&lt;/strong&gt;, click next again. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That should be it (other than confirming your blog’s name).&amp;#160; If Windows Live Writer shows a message about making a temporary post in order to detect the theme of your site, then either it hasn’t picked up your manifest file, or it’s not been able to grab the WebPreview and WebLayout files referenced in the manifest.&amp;#160; Review those URLs (ours use absolute paths to ensure that there can be no confusion) and try again (best to remove the account and add it again).&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Debugging the XML RPC Calls&lt;/h2&gt;

&lt;p&gt;As with all situations where you have an application calling another by a remote mechanism, it’s nice to be able to see what is actually being sent to and fro.&amp;#160; What we’ve done during development is to use &lt;a title="How to switch on and off Message Logging in WCF" href="http://msdn.microsoft.com/en-us/library/ms731859.aspx" target="_blank"&gt;Message Logging&lt;/a&gt; and &lt;a title="How to enable and disable WCF tracing" href="http://msdn.microsoft.com/en-us/library/ms730342.aspx" target="_blank"&gt;Tracing&lt;/a&gt; in WCF (however, it’s not exactly real-time, because until your app shuts down it doesn’t actually sign-off the trace files, causing the Service Trace Viewer to throw errors) and to use &lt;a title="The Fiddler 2 Homepage" href="http://www.fiddler2.com/fiddler2/" target="_blank"&gt;Fiddler&lt;/a&gt; to debug the Http traffic travelling between Live Writer and your service.&amp;#160; Unlike Internet Explorer, which automatically uses Fiddler when it starts up, you have to tell Live Writer to use your local proxy.&amp;#160; There’s a setting in Tools –&amp;gt; Options –&amp;gt; Web Proxy which controls this; as soon as you change that you’ll start seeing your Xml RPC Payloads going to and fro.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;There are a lot of content management systems out there, and they all offer a huge amount of features.&amp;#160; One of the primary areas of distress for anybody wanting to roll out such a site, however, is the ability to get content, update it and post it again in a way that offers the most flexibility.&amp;#160; By using a rich WYSIWYG offline editor like WLW you get a whole host of features immediately after installation, plus you also get a platform upon which you can build very quickly, thanks to its plug-in interface.&amp;#160; We have a plug-in purely for sending up additional files (like the &lt;a title="The JobServe Windows Vista Sidebar Gadget" href="http://www.labs.jobserve.com/Files.aspx/JSJobSearchGadget01.gadget" target="_blank"&gt;Vista Sidebar Gadget .gadget file&lt;/a&gt;) to the blog, because WLW only automatically uploads media content.&amp;#160; Developing this took one day to achieve.&lt;/p&gt;

&lt;p&gt;After hooking WLW into your blog, you’re then free to code the workflows behind the service that it uses.&amp;#160; This post, for example, will be posted to our blog as a draft for another member of the team to open and review.&amp;#160; They can use WLW to download the draft from it’s ‘Recently Posted’ feature.&amp;#160; If that person is happy with that content, they can send it back to the blog as a published article simply by hitting the ‘Publish’ button.&lt;/p&gt;

&lt;p&gt;We also have some role-based security behind the scenes, which hangs off of Active Directory, which means that only some people are allowed to actually publish the articles.&amp;#160; The rest are restricted to posting drafts, which must then be ‘properly’ published by someone with permissions.&lt;/p&gt;</content></entry></feed>
