<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">JobServe Labs - Articles</title><subtitle type="text">Articles from the JobServe Labs blog</subtitle><id>http://js001008.jobserve.com/jslabs.svc/feed</id><updated>2010-03-20T07:33:19Z</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?format=atom&amp;page=1&amp;pageSize=20"/><link rel="next" type="application/atom+xml" href="http://www.labs.jobserve.com/jslabs.svc/feed?format=atom&amp;page=2&amp;pageSize=20"/><link rel="last" type="application/atom+xml" href="http://www.labs.jobserve.com/jslabs.svc/feed?format=atom&amp;page=2&amp;pageSize=20"/><entry><id>c459b1be-d2dd-404b-ba44-f44ad7b4ed3d</id><title type="text">JobServe Job Search iPhone App v2.0 Released</title><updated>2010-03-11T18:00:00Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/JobServe-Job-Search-iPhone-App-v20-Released"/><category term="Connect: iPhone Job Search"/><content type="html">&lt;p&gt;The newest version of &lt;a href="http://www.labs.jobserve.com/Categories.aspx/Connect-iPhone-Job-Search" target="_blank"&gt;JobServe Connect – Job Search&lt;/a&gt; is now available on Apple iTunes.Check out the &lt;a href="http://www.labs.jobserve.com/Articles.aspx/Job-Search-v20-to-be-released-very-soon" target="_blank"&gt;features here&lt;/a&gt; and &lt;a href="itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=335516223&amp;amp;mt=8&amp;amp;s=143441" target="_blank"&gt;download it here&lt;/a&gt; (this link will open iTunes)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=335516223&amp;amp;mt=8&amp;amp;s=143441"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="iPhoneJob_banner" alt="iPhoneJob_banner" src="http://www.labs.jobserve.com/files.aspx/iPhoneJobbanner3.gif" width="468" height="60" /&gt;&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>33286877-d563-44fd-86e4-84b13a487628</id><title type="text">Job Search v2.0 to be released very soon</title><updated>2010-03-09T00:14:00Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Job-Search-v20-to-be-released-very-soon"/><category term="Connect: iPhone Job Search"/><content type="html">&lt;p&gt;We are pleased to announce that version 2.0 of our successful &lt;a href="http://www.labs.jobserve.com/Categories.aspx/Connect-iPhone-Job-Search" target="_blank"&gt;Job Search iPhone app&lt;/a&gt; is to be released very soon. We have listened to all the feedback over the last five months and believe that the new version of the JobServe Connect – Job Search iPhone app will be even more successful. Here on JobServe Labs we would like to give you a preview of what to expect and also a few screenshots of what is to come.&lt;/p&gt;  &lt;p&gt;This release contains a major upgrade in new features, suggested updates and fixes. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font color="#008080" size="4"&gt;New Features&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Salary search option provided using our two ended slider – be as specific as you need. &lt;/li&gt;    &lt;li&gt;Refine your search directly from the search results screen. &lt;/li&gt;    &lt;li&gt;Apply for jobs quickly (see below for more details) &lt;/li&gt;    &lt;li&gt;Register on JobServe quickly and easily via your iPhone. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font color="#008080" size="4"&gt;Link to Online Job Seeker record on JobServe&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Log in to your website account. &lt;/li&gt;    &lt;li&gt;View your latest jobs applied for. &lt;/li&gt;    &lt;li&gt;Run any of your Saved Searches from your online account. &lt;/li&gt;    &lt;li&gt;Get useful candidate messages from your online account. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font color="#008080" size="4"&gt;Applying For Jobs&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;JobServe announces the first fully featured Job Application system to be released on the iPhone – no web pages to navigate, completely in the app. This system fully compliments the application system provided by JobServe on the website.&lt;/p&gt;  &lt;p&gt;You will need a candidate record and a CV on your account. You can simply log in to your account via a standard web browser and upload a CV or take advantage of the AddMyCV feature – details of which are provided on the iPhone app.&lt;/p&gt;  &lt;p&gt;Once eligible you will be able to apply for jobs in as little as two taps. If you have answered all required questions before, you can simple review and tap &amp;quot;Apply&amp;quot;. However to change any answers simple review each question in our easy step by step process and then Apply.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font color="#008080" size="4"&gt;Useful updates to existing features&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Main search screen remembers options between sessions. &lt;/li&gt;    &lt;li&gt;Search assist remembers selections between sessions. &lt;/li&gt;    &lt;li&gt;Fields are better aligned when keyboard is shown. &lt;/li&gt;    &lt;li&gt;Useful keyboard toolbar buttons aid navigation. &lt;/li&gt;    &lt;li&gt;Better feedback of activity via “Please Wait” dialog. &lt;/li&gt;    &lt;li&gt;Auto scroll results to the top when paging. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;And much, much more…&lt;/p&gt;  &lt;p&gt;Don’t delay, &lt;a href="itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=335516223&amp;amp;mt=8&amp;amp;s=143441" target="_blank"&gt;download the app now&lt;/a&gt; and get the update from Apple as soon as it is available on iTunes.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.labs.jobserve.com/files.aspx/UK1Sm2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UK_1_Sm" border="0" alt="UK_1_Sm" src="http://www.labs.jobserve.com/files.aspx/UK1Smthumb.png" width="213" height="304" /&gt;&lt;/a&gt;&amp;#160;&amp;#160; &lt;a href="http://www.labs.jobserve.com/files.aspx/UK2Sm2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UK_2_Sm" border="0" alt="UK_2_Sm" src="http://www.labs.jobserve.com/files.aspx/UK2Smthumb.png" width="211" height="301" /&gt;&lt;/a&gt;&amp;#160;&amp;#160; &lt;a href="http://www.labs.jobserve.com/files.aspx/UK3Sm2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UK_3_Sm" border="0" alt="UK_3_Sm" src="http://www.labs.jobserve.com/files.aspx/UK3Smthumb.png" width="211" height="302" /&gt;&lt;/a&gt;&amp;#160;&amp;#160; &lt;a href="http://www.labs.jobserve.com/files.aspx/UK4Sm2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UK_4_Sm" border="0" alt="UK_4_Sm" src="http://www.labs.jobserve.com/files.aspx/UK4Smthumb.png" width="211" height="301" /&gt;&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>b03ee0f2-a1b3-4a13-b116-8c486bc94920</id><title type="text">Your Voice: let your voice be heard</title><updated>2010-03-02T22:28:00Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Your-Voice-let-your-voice-be-heard"/><category term="Your Voice"/><content type="html">&lt;p&gt;Today we are pleased to launch the newest member of the JobServe Labs project – &lt;a href="http://www.yourvoice.jobserve.com" target="_blank"&gt;Your Voice&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;JobServe wants to make the features, products and services available to recruiters and job seekers as useful and effective as possible. The best way to achieve this is to listen to recruiters and job seekers – so &lt;a href="http://www.yourvoice.jobserve.com" target="_blank"&gt;Your Voice&lt;/a&gt; is your opportunity to influence what we have to offer to you.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Our first release of the &lt;a href="http://www.labs.jobserve.com/Articles.aspx/Job-Search-iPhone-App-Update" target="_blank"&gt;JobServe Connect – Job Search iPhone app&lt;/a&gt; generated lots of very good feedback and questions which can now be presented on &lt;a href="http://www.yourvoice.jobserve.com/" target="_blank"&gt;Your Voice&lt;/a&gt; for everyone to read and join in.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.yourvoice.jobserve.com/" target="_blank"&gt;Your Voice&lt;/a&gt; is a simple discussion and comment forum where we will start some discussions on topics but more importantly so can YOU.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Get started with the following new discussions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.yourvoice.jobserve.com/Pages/YourVoice_DiscussionDetails.aspx?id=B850D9" target="_blank"&gt;Making Job Searching even better&lt;/a&gt; – have views on Job Search – let us know.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.yourvoice.jobserve.com/Pages/YourVoice_DiscussionDetails.aspx?id=D96088" target="_blank"&gt;Come and meet “Your Voice” in London&lt;/a&gt; – Your Voice is at a career event but what are your views on events?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;“Let your voice be heard”&lt;/p&gt;</content></entry><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>e2a3dc86-76d5-4db1-8e74-595caba3f82d</id><title type="text">Important update to iPhone Job Search</title><updated>2009-10-28T22:37:47Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Important-update-to-iPhone-Job-Search"/><category term="Connect: iPhone Job Search"/><content type="html">&lt;p&gt;A few of you had noticed that when entering a location in the iPhone App (i.e. not &lt;a href="http://www.labs.jobserve.com/Articles.aspx/Job-Search-iPhone-App-Update" target="_blank"&gt;using the Jobs Near Me option&lt;/a&gt;) the numbers of results did not match similar searches on the website. Also it appeared that changing the proximity distance for these searches had no affect – in fact all searches were running “zero miles”.&lt;/p&gt;  &lt;p&gt;Yesterday we made a change to our core web services supplying Job Search to the iPhone and we can confirm that now the proximity distance is having the desired affect.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;We would like to thank those candidates alerting us to the issue – please &lt;a href="mailto:labs.feedback@apps.jobserve.com" target="_blank"&gt;continue to feedback&lt;/a&gt; to us as you can help to make this app and others in JobServe Labs more effective.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The JobServe Labs Team&lt;/p&gt;</content></entry><entry><id>3be28036-c94a-4e2d-a72a-4bea4119ac03</id><title type="text">Job Search iPhone App Update</title><updated>2009-10-27T09:47:37Z</updated><author><name>JobServe</name><uri>http://www.labs.jobserve.com</uri></author><link rel="alternate" href="http://www.labs.jobserve.com/Articles.aspx/Job-Search-iPhone-App-Update"/><category term="Connect: iPhone Job Search"/><content type="html">&lt;p&gt;The JobServe Job Search iPhone App (&lt;a href="itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=335516223&amp;amp;mt=8&amp;amp;s=143441" target="_blank"&gt;available here&lt;/a&gt;) has been on the App Store for just under a week and we are very pleased with the overall reception so far. In this article we would like to discuss the feedback so far and explain some of the issues experienced.&lt;/p&gt;  &lt;p&gt;Thank you to all the users that have taken the time to email us with constructive and useful feedback, we have had over 3,000 downloads and at least 50 emails which range from feature requests and suggestions to possible issues with the search or function of the app.&lt;/p&gt;  &lt;p&gt;Key features requested:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Provide Salary/Rate search options &lt;/li&gt;    &lt;li&gt;Allow user to set the number of results displayed per page &lt;/li&gt;    &lt;li&gt;Access Saved Searches from the JobServe website &lt;/li&gt;    &lt;li&gt;Apply for Jobs directly from the App &lt;/li&gt;    &lt;li&gt;Display the Job Reference and recruiter Telephone number if available &lt;/li&gt;    &lt;li&gt;Allow results to be displayed in Best Match or Posted Date Descending order &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;   &lt;br /&gt;Suggested improvements to current functionality:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Change the layout of the results to fit more jobs on the screen – better use of real estate &lt;/li&gt;    &lt;li&gt;Make the settings option more visible to users &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;   &lt;br /&gt;Issues highlighted:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Jobs Near Me functionality causes app crashes for some users &lt;/li&gt;    &lt;li&gt;Email job from Full Description screen fails &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So we have a good set of request and suggestions already. Currently under review by Apple is a new version v1.01 which will provide new features 2 and 5 above. Cosmetic changes to the layout will display more jobs per page and the settings option is more visible.&lt;/p&gt;  &lt;p&gt;In terms of bugs all should be fixed in this new release.&lt;/p&gt;  &lt;p&gt;Jobs Near Me – This uses the iPhone API &lt;a href="http://developer.apple.com/iphone/library/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html" target="_blank"&gt;CLLocationManager&lt;/a&gt; class and for many users when selected this class returns the location co-ordinates quickly and accurately. However some users experience when in certain locations that this crashes – we have many reports of the same user using the app successfully in different locations but crashing in other locations. Under all testing scenarios we did not experience this, and although not a perfect excuse, we released this with belief that the required precautions were taken. On closer analysis it appears that the CLLocationManager may be returning two results very quickly – even though we have requested specifically to &lt;a href="http://www.iphonedevsdk.com/forum/iphone-sdk-development/2299-cllocationmanager-stopupdatinglocation-not-working.html" target="_blank"&gt;stop updating the location&lt;/a&gt;. Users experiencing the crashing sometimes saw results very quickly or just bombed out on the first screen. Users could then use the Location box for searching instead as a workaround. &lt;/p&gt;  &lt;p&gt;The new release will be out as soon as possible and we value your continued feedback. &lt;/p&gt;  &lt;p&gt;Following this release we will be planning another release which will contain Sort Order options and Salary Searching. &lt;/p&gt;  &lt;p&gt;We are also working on the Application platform which will allow users to apply for jobs directly from their phone using our Job Application process similar to the JobServe website. The only requirement will be to have a JobServe candidate record and maintain a CV on the website.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="10" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://www.labs.jobserve.com/files.aspx/S14.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="S1" border="0" alt="S1" src="http://www.labs.jobserve.com/files.aspx/S1thumb1.png" width="284" height="406" /&gt;&lt;/a&gt; &lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;a href="http://www.labs.jobserve.com/files.aspx/S24.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="S2" border="0" alt="S2" src="http://www.labs.jobserve.com/files.aspx/S2thumb1.png" width="284" height="407" /&gt;&lt;/a&gt; &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;</content></entry><entry><id>cc44b58f-474e-4145-a7a6-333aba6ce045</id><title type="text">JobServe Connect – Job Search for the iPhone released</title><updated>2009-10-21T15:21:02+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/JobServe-Connect--Job-Search-for-the-iPhone-released"/><category term="Connect: iPhone Job Search"/><content type="html">&lt;p&gt;We are happy to report that the JobServe iPhone app “JobServe Connect – Job Search” has now been approved by Apple and is available from the App Store on iTunes. We thank all the users that pre-registered for the app and you should all have received your launch link to download the App.&lt;/p&gt;  &lt;p&gt;So far response has been very good and we encourage even more of you to send us emails with suggestions and general feedback, we’ll post details of what features will be making the next release as soon as we can.&lt;/p&gt;  &lt;p&gt;If you would like to get the iPhone app now please use this link &lt;a href="itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=335516223&amp;amp;mt=8&amp;amp;s=143441" target="_blank"&gt;to download from iTunes&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>1e14bb1f-dd18-46c3-afb2-d89761688e61</id><title type="text">JobServe Connect – iPhone first mobile platform soon</title><updated>2009-10-19T16:23:18+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/JobServe-Connect--iPhone-first-mobile-platform-soon"/><category term="iPhone"/><content type="html">&lt;p&gt;Currently we are awaiting confirmation from Apple that our Job Search iPhone app is going live (more details below) and this will pave the way to continued reach of JobServe services to other devices. The rise of smart mobile devices, with 35 Million iPhones and 65 Million Blackberry devices worldwide, shows that this is a popular channel to reach our customers – Job Seeker and Recruiter alike.&lt;/p&gt;  &lt;p&gt;JobServe Labs has been committed to providing different ways to access JobServe, we have launched the &lt;a href="http://www.labs.jobserve.com/Projects.aspx/Google-Desktop-Job-Search" target="_blank"&gt;Google Desktop Gadget&lt;/a&gt; and the &lt;a href="http://www.labs.jobserve.com/Projects.aspx/Windows-Vista-Sidebar-Gadget" target="_blank"&gt;Windows Vista Sidebar Gadget&lt;/a&gt;, both have proved very popular and are often being updated with new features.&lt;/p&gt;  &lt;p&gt;Currently we are concentrating on providing Job Seekers more ways to search for jobs and with the imminent release of the first JobServe iPhone App we will bring the ease of job searching and the large number of UK, US, Canadian, Australian and global jobs to even more people. Like all developments within the Labs project the iPhone Job Search app is only the first iteration. We have already planned updates and other apps which will make up the family – JobServe Connect.&lt;/p&gt;  &lt;h2&gt;JobServe Connect – What is it?&lt;/h2&gt;  &lt;p&gt;JobServe Connect is the umbrella term for the suite of products developed by JobServe Labs to bring JobServe products and services to more users and to enable better communication between Job Seekers and Recruiters as well as JobServe and its customers. We will provide more and more channels to enable anyone to talk to JobServe and help shape the job board of tomorrow through useful features and technology. We want feedback, we provide our &lt;a href="http://twitter.com/JsLabs" target="_blank"&gt;Twitter feed @JSLabs&lt;/a&gt; and we have our articles with news of what we are working on. So we encourage you to read, email, tweet about articles you like and help &lt;a href="http://twitter.com/home?status=%23JobServe+Labs+details+of+push+for+mobile+devices+read+here+http:%2F%2Fbit.ly%2F4w7U3V" target="_blank"&gt;Spread The Word – Tweet This Article&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;No iPhone? What else&lt;/h2&gt;  &lt;p&gt;We asked the same question to our Job Seekers and we have had some predictable but great results. Not too surprisingly the top non-iPhone platform requested was Blackberry. We can confirm that we are now working on porting over our Job Search iPhone app so as soon as possible we will have a Job Search Blackberry App. Remember that JobServe Labs will contain information on this and future releases.&lt;/p&gt;  &lt;p&gt;Popular other platforms were Symbian based devices, Android and Windows Mobile. Keep an eye on JobServe Labs as these apps get released in the coming months.&lt;/p&gt;  &lt;h2&gt;Any more news on the Job Search iPhone App?&lt;/h2&gt;  &lt;p&gt;The JobServe iPhone app is called “JobServe Connect – Job Search” and will launch very soon as a sneak preview here is the main screenshot as well as a list of the primary features you can expect. There is still time to get a priority link – simply email &lt;a href="mailto:iphone.interest@apps.jobserve.com"&gt;iphone.interest@apps.jobserve.com&lt;/a&gt; the word &lt;strong&gt;iPhone&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="10" width="536"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="243"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://www.labs.jobserve.com/Files.aspx/ukjs3gs1small.jpg" /&gt;&lt;/td&gt;        &lt;td valign="top" width="270"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://www.labs.jobserve.com/Files.aspx/ukjs3gs2small.jpg" /&gt;&lt;/td&gt;        &lt;td valign="top" width="21"&gt;         &lt;p&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="243"&gt;         &lt;p align="center"&gt;UK Version (Home screen)&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="270"&gt;         &lt;p align="center"&gt;UK Version (Results)&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="21"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="243"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="270"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="21"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160; &lt;/p&gt;  &lt;h3&gt;Features:&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;Simple JobServe Job Search &lt;/li&gt;    &lt;li&gt;Search Jobs Near You &lt;/li&gt;    &lt;li&gt;Settings providing Proximity, Days since Job posted and Country &lt;/li&gt;    &lt;li&gt;Favourite Jobs &lt;/li&gt;    &lt;li&gt;Email Favourites or individual Jobs &lt;/li&gt;    &lt;li&gt;Suggested Jobs - Get a custom list of other jobs you may be interested in &lt;/li&gt;    &lt;li&gt;Automatic Search History - Only type the search once &lt;/li&gt;    &lt;li&gt;Search Assist - The new iPhone search wizard helps you build a search &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Version 1.0 of the Job Search iPhone App has concentrated on ease of use and speed.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;We will let you know as soon as the iPhone App is live.&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>616e5f46-0f49-413f-b9e8-6d3dfd6dfbfb</id><title type="text">JobServe Job Search coming to the iPhone</title><updated>2009-10-14T22:05:36+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/JobServe-Job-Search-coming-to-the-iPhone"/><category term="iPhone"/><content type="html">&lt;p&gt;The JobServe app for job searching is coming to the iPhone and iPod Touch very soon. We are very excited about the imminent launch of the first JobServe app on this platform&amp;#160; and we want as many of you to join in the release as possible.&lt;/p&gt;  &lt;p&gt;If you would like to be sent a priority link to download the JobServe App as soon as it is available simply send an email to &lt;a href="mailto:iphone.interest@apps.jobserve.com"&gt;iphone.interest@apps.jobserve.com&lt;/a&gt; with the subject line &lt;strong&gt;iPhone&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;We will be posting much more information on this app and the other apps in development, very soon. Also we are going to bring JobServe to as many platforms as possible in the coming months.&lt;/p&gt;  &lt;p&gt;The app - “&lt;strong&gt;JobServe Connect – Job Search&lt;/strong&gt;” will be released very soon and your feedback will be very important to helping shape future releases.&lt;/p&gt;  &lt;p&gt;Keep up to date with information from us on the website or follow us on &lt;a href="http://twitter.com/jslabs" target="_blank"&gt;Twitter @JSLabs&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>88b74205-5203-4872-a997-c3267dde5938</id><title type="text">Google Desktop Gadget v0.2 released!</title><updated>2009-10-14T18:00:46+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/Google-Desktop-Gadget-v02-released"/><category term="Google Desktop Job Search"/><content type="html">&lt;p&gt;Following on from the recent release of &lt;a title="Our article describing the new version of the Windows Sidebar Job Search Gadget" href="http://www.labs.jobserve.com/Articles.aspx/Sidebar-Gadget-v03-Released" target="_blank"&gt;v0.3 of the Windows Sidebar Gadget&lt;/a&gt;, as promised we’ve now updated our Google Gadget to include most of the same feature-set.&lt;/p&gt;  &lt;p&gt;If you want to go and test drive it now, &lt;a title="Download the Google Gadget now!" href="http://www.labs.jobserve.com/Files.aspx/JSJobSearch.gg"&gt;simply go ahead and download it&lt;/a&gt;!&amp;#160; If you’ve previously downloaded it from the &lt;a title="The JobServe Labs Job Search gadget on the Google Gadget Directory" href="http://desktop.google.com/plugins/i/jsjobsearch_labsfeed.html" target="_blank"&gt;Google Gadget Directory&lt;/a&gt;, then you can still download it straight from us – but it’ll also appear as an update in your gadget list after few days of it being live.&lt;/p&gt;  &lt;h2&gt;So what’s changed?&lt;/h2&gt;  &lt;p&gt;The original gadget allowed you to search for jobs with a particular skills keyword search, in a particular location and country.&amp;#160; The first minor improvement we’ve made is to add a new country: ‘All’:&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="JobServe Google Gadget - All Countries" border="0" alt="JobServe Google Gadget - All Countries" src="http://www.labs.jobserve.com/files.aspx/ggadgetv02sshot01d6abf8e8-619b-412c-bb8b-600d1a229741.png" width="201" height="295" /&gt; &lt;/p&gt;  &lt;p&gt;As you can see above – the country selection is ‘All countries and areas’.&amp;#160; Be careful with this one if you are after a single location in the world.&amp;#160; In the query above, for example, I’ve searched for SQL jobs in ‘London’.&amp;#160; This &lt;em&gt;could&lt;/em&gt; mean &lt;a title="Google Maps - Centred on London, England" href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=london,+uk&amp;amp;sll=37.0625,-95.677068&amp;amp;sspn=42.445866,68.642578&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=London,+United+Kingdom&amp;amp;z=14"&gt;London, UK&lt;/a&gt;; or &lt;a title="Google Maps centred on London, Middlesex, ON in Canada" href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=london,+ON&amp;amp;sll=51.500152,-0.126236&amp;amp;sspn=0.0327,0.067034&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=London,+Middlesex+County,+Ontario,+Canada&amp;amp;z=11" target="_blank"&gt;London, ON in Canada&lt;/a&gt; (or indeed any one of the other numerous locations around the world that are called ‘London’.&lt;/p&gt;  &lt;p&gt;Other classic ambiguous locations are Birmingham, Cleveland and Colchester (all UK/US location cross-overs); of course we can’t provide an exhaustive list here!&lt;/p&gt;  &lt;p&gt;The real power of a worldwide search, however, is if you are the kind of person who regularly moves all around the world – the IT contractors among you, for example may well fit into this category.&lt;/p&gt;  &lt;h2&gt;The Options Dialog&lt;/h2&gt;  &lt;p&gt;Talking of Contractors, we also have four new options that you can use to modify your search.&amp;#160; You’ll notice the spanner/wrench icon next to the ‘search’ button above.&amp;#160; Clicking on this launches the new options dialog:&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="Google Gadget - Options (Search Customisation)" border="0" alt="Google Gadget - Options (Search Customisation)" src="http://www.labs.jobserve.com/files.aspx/ggadgetv02sshot02optionsf0437f63-7d6e-42ef-b7e1-a2d2c4e1372c.png" width="310" height="240" /&gt; &lt;/p&gt;  &lt;p&gt;The emphasis here is functionality – not look and feel!&lt;/p&gt;  &lt;p&gt;A quick run through of the different options:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Job Type&lt;/strong&gt;: Select from Any (the original default), Permanent or Contract. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Per Page&lt;/strong&gt;: The results from our web services are paged, previously you were fixed to 20 results per page, but now you can configure it in steps up to a maximum of 100 jobs per page. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Job Age&lt;/strong&gt;: The previous search defaulted to pages posted in the last 7 days.&amp;#160; Now you can select from 1 to 7 days; as well as the ‘Today Only’ option – which will include only jobs posted since midnight GMT today. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Distance&lt;/strong&gt;: Allows you to specify the maximum distance a job is allowed to be from your specified location in order to be included in your search.&amp;#160; There is no unit selection (miles/km) because it is interpreted differently according to the country in which you search.&amp;#160; E.g. on a UK search the value is interpreted as miles, but on a US search it’s interpreted as kilometres. &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;What’s next?&lt;/h2&gt;  &lt;p&gt;The next iteration will see industry selection and ‘email me this job’ functionality which we have already released in our &lt;a title="The Windows Sidebar Gadget Project" href="http://www.labs.jobserve.com/Projects.aspx/Windows-Vista-Sidebar-Gadget" target="_blank"&gt;Windows Sidebar Gadget&lt;/a&gt;.&amp;#160; We will endeavour to get this out as soon as possible, but we hope in the meantime that this will satiate your job-searching needs!&lt;/p&gt;  &lt;p&gt;As always, keep coming back to this site, &lt;a title="The JobServe Labs Atom Feed" href="http://www.labs.jobserve.com/jslabs.svc/feed" target="_blank"&gt;or subscribe to our Atom feed&lt;/a&gt; – as we have some very exciting developments on the way in the next few months!&lt;/p&gt;</content></entry><entry><id>f7051770-5310-4660-8c58-ff6523e2c6e2</id><title type="text">Sidebar Gadget v0.3 Released!</title><updated>2009-10-07T11:19:14+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/Sidebar-Gadget-v03-Released"/><category term="Windows Vista Sidebar Gadget"/><content type="html">&lt;p&gt;Today sees the launch of the next enhancement to the Windows Sidebar Gadget: v0.3.&amp;#160; To get hold of it, simply &lt;a title="Download the latest JobServe Job Search Windows Sidebar gadget" href="http://www.labs.jobserve.com/Files.aspx/JSJobSearchGadget03.gadget"&gt;download it now&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;The key enhancements are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;New ‘Distance’ selection dropdown on the settings dialog&lt;/strong&gt;.&amp;#160; Provide a hint to our search engine as to how far you want to travel out of the location you specify on a search. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;New ‘Industry’ selection list&lt;/strong&gt;.&amp;#160; Now you can isolate your searches to one industry, or a combination of industries, within which our recruiters post jobs.&amp;#160; So now, if you’re only looking for ‘Sales’ jobs, you can select that industry only and then use the skills search field to specify kind of sales job you want. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Added ‘Today Only’ option for job age&lt;/strong&gt;.&amp;#160; If you use our gadget frequently (and we know that a good number of you do!), then you can now restrict your results to only those jobs that have been posted today.&amp;#160; An important thing to note with this feature is that at midnight UK time, all results will reset and your search will start to build up new results. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Added an “All Countries” selection in the country dropdown on the settings dialog&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Added ‘Email me this job’ feature&lt;/strong&gt;.&amp;#160; On our settings dialog you can now provide your email address (&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; we &lt;u&gt;never&lt;/u&gt; give out your email address to anybody, so it’ll be in safe hands!&lt;/em&gt;).&amp;#160; If you do this, then when you expand the full-job details, you’ll see a new link in addition to the Apply Now link.&amp;#160; When you click on the ‘Email me this job’, we will send you the full-text of that job and a link to apply to it.&amp;#160; You can only queue one email request per job in one 24 hour period; but there is no limit on the number of jobs you can receive by email. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Screenshots&lt;/h2&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="vistagadget_03_settings" border="0" alt="vistagadget_03_settings" src="http://www.labs.jobserve.com/files.aspx/vistagadget03settings21456c89-4b69-4911-a4c2-543415d31b5f.jpg" width="365" height="435" /&gt;&lt;/p&gt;  &lt;p&gt;The new settings dialog.&amp;#160; Note the 3 new fields: Email, Distance and Industries.&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="vistagadget_03_jobdetails" border="0" alt="vistagadget_03_jobdetails" src="http://www.labs.jobserve.com/files.aspx/vistagadget03jobdetails0b7c69d2-eea3-4f50-a332-2e92fe1763c7.jpg" width="570" height="340" /&gt; &lt;/p&gt;  &lt;p&gt;New Job Details Page – when you’ve entered an email address on the settings page, run a new search and open up a job’s details.&amp;#160; You will see the ‘Email me this job’ link.&amp;#160; When you click on the link, its text will change to let you know whether or not the email has been sent:&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="vistagadget_03_jobdetails_email_sent" border="0" alt="vistagadget_03_jobdetails_email_sent" src="http://www.labs.jobserve.com/files.aspx/vistagadget03jobdetailsemailsent5f32124a-14b9-4a08-add8-2d215888c101.jpg" width="573" height="343" /&gt; &lt;/p&gt;  &lt;p&gt;If you’ve already been sent an email for this job within the last 24 hours, then the link will change to “Already Sent Today!”.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;What about my Google Gadget?&lt;/h2&gt;  &lt;p&gt;Yes, if you’re a fan of the &lt;a href="http://www.labs.jobserve.com/Projects.aspx/Google-Desktop-Job-Search" target="_blank"&gt;Google Job Search Gadget&lt;/a&gt;, you’ll be wanting to know when all these features, plus the rest of the configuration features that were added in V0.2, will be available.&amp;#160; Rest assured, we are working on this as we speak and you can expect an updated version soon.&lt;/p&gt;  &lt;h2&gt;Anything else in the pipeline?&lt;/h2&gt;  &lt;p&gt;You bet!&amp;#160; We are expanding the idea of “JobServe any place, anywhere” and there are some very exciting developments on the way very soon indeed.&amp;#160; Keep coming back to the site, or &lt;a title="The JobServe Labs Atom Feed" href="http://www.labs.jobserve.com/jslabs.svc/feed" target="_blank"&gt;subscribe to our Atom feed&lt;/a&gt; to keep yourself in the loop.&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://www.lordzoltan.org/blog/post/Serializing-to-attributes-in-WCF-with-DataContractSerializer.aspx" 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>2fad67c8-896b-4a2c-9b69-dc6fdb9a4487</id><title type="text">Search for Jobs from your Google Desktop!</title><updated>2009-07-27T11:20:13+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/Search-for-Jobs-from-your-Google-Desktop"/><category term="Google Desktop Job Search"/><content type="html">&lt;p&gt;&lt;em&gt;If you just want to get going without reading this article - &lt;a href="http://www.labs.jobserve.com/Files.aspx/JSJobSearch.gg" target="_blank"&gt;download the gadget now&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Soon after JobServe Labs was launched, &lt;a href="http://www.labs.jobserve.com/Projects.aspx/Windows-Vista-Sidebar-Gadget" target="_blank"&gt;we launched the Windows Desktop Job Search Gadget&lt;/a&gt; – which enables you to execute job searches, and view full job details, directly from your Windows Desktop.&amp;#160; Immediately we saw huge interest in this gadget (as a result &lt;a href="http://www.labs.jobserve.com/Articles.aspx/Sidebar-Gadget-v02-Released" target="_blank"&gt;we updated it to version 0.2 today&lt;/a&gt;), which has convinced us that providing our services in ways other than the web-browser is the right way to move forward.&lt;/p&gt;  &lt;p&gt;Not everybody was happy, though, because not everybody is running Windows as their preferred desktop operating system, and even if they are it’s still likely to be Windows XP or 2003 – which doesn’t support the Windows Sidebar platform.&lt;/p&gt;  &lt;p&gt;So, immediately we got back on the case and started looking at an alternative Job Search gadget that could be used by even more people; and which can be accessed from Linux, Mac OS-X or Windows.&amp;#160; Mac OS-X, like Windows Vista or 7, has it’s own proprietary Gadget platform – &lt;a title="The Mac OS-X Dashboard Widget Directory" href="http://www.apple.com/downloads/dashboard/" target="_blank"&gt;the Dashboard and it’s Widgets&lt;/a&gt;, and we did look at developing a stand-alone version for that.&amp;#160; However, in the end, we’ve decided to go for the Google Desktop Gadget Platform as it’s the one that probably has the most users, and it is indeed available on all three aforementioned OS flavours.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;What does it look like?&lt;/h2&gt;  &lt;p&gt;Here are two screenshots of the Gadget:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.labs.jobserve.com/files.aspx/googlegadgetv1winshot2.jpg" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Job Search Google Desktop Gadget on Windows 2003 x64" border="0" alt="Job Search Google Desktop Gadget on Windows 2003 x64" src="http://www.labs.jobserve.com/files.aspx/googlegadgetv1winshotthumb.jpg" width="684" height="630" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is from one of our Windows Server 2003 x64 development boxes.&amp;#160; Click on the image for a larger version.&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="Job Search Google Desktop Gadget on Ubuntu 9.04" border="0" alt="Job Search Google Desktop Gadget on Ubuntu 9.04" src="http://www.labs.jobserve.com/files.aspx/googlegadgetv1ubuntushot3b9db7eb-ea72-4d7d-a9c5-f5f0513fde8b.jpg" width="684" height="459" /&gt; &lt;/p&gt;  &lt;p&gt;This is from an &lt;a href="http://www.ubuntu.com/" target="_blank"&gt;Ubuntu 9.04&lt;/a&gt; virtual machine that we’re running inside Virtual PC on a Dev machine.&amp;#160; We used &lt;a title="How to install Ubuntu 8.10 under Virtual PC (works also for 9.04)" href="http://arcanecode.com/2008/11/10/installing-ubuntu-810-under-microsoft-virtual-pc-2007/" target="_blank"&gt;these very helpful steps to get everything up and running&lt;/a&gt;, and all-told it took just 15 minutes.&amp;#160; If you have a windows domain-based corporate web-proxy, however, you might want to get your support team to allow your Ubuntu box out of it without having to authenticate (or push it through another proxy that doesn’t require authentication), as we couldn’t get web access working properly until we did that.&amp;#160; Firefox’s proxy configuration worked fine, but the system-wide proxy configuration didn’t – there appears to be a bug with NTLM authentication.&lt;/p&gt;  &lt;p&gt;Incidentally, if you’re running the Ubuntu Jaunty and you need to install Google Gadgets for Linux, then you should find it on the package manager in the ‘Internet’ section – there’s a GTK and a Qt version.&amp;#160; If you’re running openSUSE, then the binaries are also included in the official repository.&amp;#160; &lt;a title="Where to get the binary packages for GGL" href="http://code.google.com/p/google-gadgets-for-linux/wiki/BinaryPackages" target="_blank"&gt;The GGL team have written some excellent documentation about where to get the binaries from&lt;/a&gt;, depending on the distribution that you run.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you’re running Google Desktop for Mac OS-X, you &lt;em&gt;should&lt;/em&gt; be able to use this gadget as well, as we’ve &lt;a title="Writing a cross-platform gadget - Google Code" href="http://code.google.com/apis/desktop/docs/crossplatform.html#dashboard" target="_blank"&gt;followed all the guidelines on how to ensure cross-platform functionality&lt;/a&gt;. Despite all this, however, there is still an element of the dark-arts about this, and we’d really appreciate any feedback from Mac users as to how successful we’ve been in delivering a desktop search for you guys.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Is it as fast as the Windows Sidebar Gadget?&lt;/h2&gt;  &lt;p&gt;In a word, yes.&amp;#160; The code is using exactly the same JSON web service that the windows gadget uses, the only differences are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;How the UI has been implemented – since the Windows Gadget platform is html and JavaScript based, whereas the Google Desktop Gadget platform uses a proprietary XML format for UI, and &lt;strong&gt;&lt;em&gt;strict&lt;/em&gt;&lt;/strong&gt; JavaScript for application code. &lt;/li&gt;    &lt;li&gt;How we talk to the web service.&amp;#160; In the Windows Gadget &lt;a title="The jQuery website" href="http://jquery.com/" target="_blank"&gt;we’ve embedded the excellent jQuery library&lt;/a&gt;, and use it’s &lt;a title="The $.getJSON method - jQuery documentation" href="http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback" target="_blank"&gt;$.getJSON method&lt;/a&gt; to get the search results.&amp;#160; &lt;a title="Google Code - Excellent article about using XMLHttpRequest" href="http://code.google.com/apis/desktop/articles/e9.html" target="_blank"&gt;With the Google Gadget we have to program against XMLHttpRequest directly&lt;/a&gt; in order to be sure to maximise cross-platform compatibility. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;How to use it&lt;/h2&gt;  &lt;p&gt;You have two editable textboxes to use to specify your query terms.&amp;#160; The ‘skills’ box is &lt;em&gt;what&lt;/em&gt; you’re looking for, and the ‘location’ box is, clearly, &lt;em&gt;where &lt;/em&gt;you want it to be.&amp;#160; This should not be a country – since you also have a country dropdown that you should use for this – it should ideally be a town, village, county or state.&amp;#160; Our skills search query (and location query for that matter) supports Boolean operators (AND, OR, NOT) and quoted expressions (“Visual Basic”, “Business Objects”, “Management Training”).&amp;#160; For example, if you want a C# job that also involves Sql Server (quoted expression), but you don’t want to work in London – then this is the kind of search you need:&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="Advanced Job Search in Ubuntu 9.04" border="0" alt="Advanced Job Search in Ubuntu 9.04" src="http://www.labs.jobserve.com/files.aspx/googlegadgetv1advancedsearch895cb55a-1452-440d-b815-d018620b5bf0.jpg" width="684" height="459" /&gt; &lt;/p&gt;  &lt;p&gt;The gadget will always remember your last search parameters, so if you remove the gadget from your desktop and put it back on again, your last search will already be pre-filled.&lt;/p&gt;  &lt;p&gt;The gadget is fully resizable whether it is docked or not.&amp;#160; The value of resizing horizontally beyond a certain width is pretty minimal, however, resizing vertically is a huge plus as it means you can see more results in one go.&amp;#160; &lt;/p&gt;  &lt;p&gt;The inner results list is scrollable by using the green buttons that appear at the top and bottom.&amp;#160; We would like to have used a scrollbar for this, however, &lt;a title="Read the section &amp;quot;How to implement a scrollbar&amp;quot; in this article" href="http://code.google.com/apis/desktop/articles/e2.html" target="_blank"&gt;the scrollbars for DIV elements and list boxes do not appear within those elements when the gadget is docked&lt;/a&gt;.&amp;#160; We could have used the Scrollbar control to implement this, however the problem with that is that it takes away valuable horizontal space in which to display our job results.&lt;/p&gt;  &lt;p&gt;Our solution was to use the beginAnimation method of the View object when either our up or down buttons are clicked.&amp;#160; The gadget calculates the page size, in terms of result-count, that can currently be displayed based on its height.&amp;#160; This is turned into pixels (by virtue of the fact that each of our results is a fixed height), and then we slide the results list up or down by that number of pixels in our animation call-back.&amp;#160; &lt;a title="Animating a Google Gadget - scaling, rotation, opacity et al" href="http://code.google.com/apis/desktop/articles/e7.html" target="_blank"&gt;This article contains lots of examples of how to animate your own Google gadget&lt;/a&gt;; the thing we like the most about this is that it’s not tied down to directly visible attributes of the UI: the beginAnimation method is simply a timed slide between two values, therefore how you interpret that value is entirely up to you.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Ideas and suggestions&lt;/h2&gt;  &lt;p&gt;As always, we’ll be looking for ways to make this gadget even better to make it easier and faster to use; we also really want your ideas and suggestions for this or any other gadget or feature.&amp;#160; You never know, you could be the source of the next idea to come out of JobServe Labs!&lt;/p&gt;</content></entry><entry><id>af1699a4-f10b-480d-a92f-16ffda6c7fba</id><title type="text">Sidebar Gadget v0.2 Released!</title><updated>2009-07-24T14:23:28+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/Sidebar-Gadget-v02-Released"/><category term="Windows Vista Sidebar Gadget"/><content type="html">&lt;p&gt;We’ve updated our Windows Gadget – you can download the latest version &lt;a title="Download link for v0.3 of the Windows Gadget" href="http://www.labs.jobserve.com/Files.aspx/JSJobSearchGadget03.gadget"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We’ve had a phenomenal response to the initial version of the Windows Sidebar Gadget, we’re seeing a lot of people from all over the world running searches and applying for jobs – so we’re really pleased that our hard work has been appreciated!&lt;/p&gt;  &lt;p&gt;We’re really impressed, also, with the number of different countries that people are looking for jobs in, and we hope that those of you who experience low bandwidth to our servers are finding the response times for this search to be excellent.&lt;/p&gt;  &lt;p&gt;As proof of our continued support of this alternative way in which you can access JobServe’s services, we’ve added a couple of new features that we hope will make the gadget easier for you to use.&amp;#160; They mainly centre around the options dialog (screenshot taken &lt;a title="Get the Release Candidate of Windows 7 now" href="http://www.microsoft.com/windows/windows-7/get/download.aspx" target="_blank"&gt;from Windows 7 RC&lt;/a&gt; running on &lt;a title="Get hold of Microsoft&amp;#39;s Virtual PC 2007 - it&amp;#39;s free" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=04D26402-3199-48A3-AFA2-2DC0B40A73B6&amp;amp;displaylang=en" target="_blank"&gt;Virtual PC 2007&lt;/a&gt;):&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="vistagadget_v0_2_settings" border="0" alt="vistagadget_v0_2_settings" src="http://www.labs.jobserve.com/files.aspx/vistagadgetv02settings0d21b3ca-fa12-4bd8-b0e7-d35f3a5bc7e7.jpg" width="637" height="453" /&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Added Job Type selection, so you can now specify Permanent/Contract or both. &lt;/li&gt;    &lt;li&gt;Added Job Age selection, so you can narrow down you searches only to jobs that have appeared in the last &lt;em&gt;n&lt;/em&gt; days up to 7. &lt;/li&gt;    &lt;li&gt;Added Results Per Page selection – now you can have as few as 5 jobs per page, up to a maximum of 100 jobs per page!&amp;#160; (Note, this limit is imposed at the server-side, so any attempt to increase it, either by editing the .js files or by manually firing the query from the browser will unfortunately fail!). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You’ll also notice a Help icon on the main body of the gadget, this just offers a few pointers on how to search.&amp;#160; Also, we have now introduced auto-update functionality – the next time we update the gadget, you’ll see a little yellow exclamation mark that you can click on, which will contain a link to download the latest version of the gadget.&lt;/p&gt;  &lt;p&gt;The final big difference with this version of the gadget, is that it is &lt;a title="MSDN information about SignTool.exe" href="http://msdn.microsoft.com/en-us/library/8s9b9yaz.aspx" target="_blank"&gt;now digitally signed by authenticode using the signtool.exe utility&lt;/a&gt; – and all of our future Windows Gadgets will be, too (therefore be wary of any gadgets that pretend to be JobServe gadgets).&amp;#160; When you install the gadget now you should see ‘JobServe Ltd’ as the publisher:&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="vistagadget_v0_2_signing" border="0" alt="vistagadget_v0_2_signing" src="http://www.labs.jobserve.com/files.aspx/vistagadgetv02signing9462d965-6a67-4f6b-ac61-c5a093565a60.jpg" width="418" height="270" /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You can download the new gadget from &lt;a title="Download link for v0.3 of the Windows Gadget" href="http://www.labs.jobserve.com/Files.aspx/JSJobSearchGadget03.gadget"&gt;here&lt;/a&gt;.&amp;#160; If you have the previous version installed, it won’t necessarily be overwritten – simply remove the old gadget from your sidebar/desktop, and then uninstall it from the Gadget gallery.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Notes to anybody who downloaded the gadget from the &lt;/em&gt;&lt;a href="http://www.labs.jobserve.com/Articles.aspx/Search-for-jobs-from-your-Windows-Desktop"&gt;&lt;em&gt;original article written about this gadget&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: The download links were changed in the old article to point to the new version at the same time that this article was published.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;As always, please direct any of your comments to the feedback email at the bottom of this page!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy job hunting!&lt;/p&gt;</content></entry><entry><id>3aa2b8ab-402c-4c77-a6f1-72e653c7bcf0</id><title type="text">JobServe needs your talent</title><updated>2009-07-20T23:56: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/JobServe-needs-your-talent"/><category term="General"/><content type="html">&lt;p&gt;There are great things going on in JobServe Technology and we are always on the lookout for talented, enthusiastic, results driven developers to join the team. If you are an experienced .NET developer then read on, if you are a Java Developer – ever thought what it would be like on the Microsoft side?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font color="#ff0000" size="4"&gt;HANG ON : &lt;a href="http://www.jobserve.com/recruiterJobListing.aspx?cid=26698" target="_blank"&gt;JobServe doesn’t always want only IT people – check out JobServe recruitment for other positions.&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;We have two positions available to join the IT Development team here in JobServe UK, working from the head office in &lt;a href="http://www.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=tiptree+essex&amp;amp;sll=37.0625,-95.677068&amp;amp;sspn=96.168524,155.390625&amp;amp;ie=UTF8&amp;amp;z=14&amp;amp;iwloc=A" target="_blank"&gt;Tiptree, Essex&lt;/a&gt; (not far from Colchester or Chelmsford). We have a very experienced team of developers, spanning many years of job board development but we are always looking for new blood to “stir”, “question”, “challenge” and “integrate” with our team. The coming year of development projects is nothing more than staggering and is leaving our team pale at the prospect – &lt;strong&gt;Can you come and help them out?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So what do we want? &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Experience&lt;/strong&gt; : ASP.NET/C#/VB.NET of at least 4 Years for the Developer Role or 1-2 years for the Junior Role&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Desirable Skills&lt;/strong&gt; :&amp;#160; Team Foundation Server, SQL Server or other relational database, exposure to web technologies. Demonstrate clear commercial project experience.&lt;/p&gt;  &lt;p&gt;You must be able to self-motivate, stick to tight deadlines, work very well in a team and be a top analyst.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Benefits&lt;/strong&gt; : Developer role &lt;strong&gt;to £40K&lt;/strong&gt;, Junior Role &lt;strong&gt;to 28K&lt;/strong&gt;. There is a pension, performance related bonus and technically challenging work.&lt;/p&gt;  &lt;p&gt;If you want a challenge, want to use new technology, want to make a difference in a small company with massive ideas then &lt;strong&gt;Apply NOW&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Simply forward your CV along with why you want to work for JobServe to &lt;a href="mailto:labs.personnel@apps.jobserve.com"&gt;labs.personnel@apps.jobserve.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;or &lt;a href="http://www.jobserve.com/recruiterJobListing.aspx?cid=26698" target="_blank"&gt;Apply Online for the right jobs here&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>