<?xml version="1.0" encoding="utf-8"?>
<blog root-url="http://localhost:1608/SUBWebV2/" date-created="2006-05-06T23:06:32" xmlns="http://www.blogml.com/2006/09/BlogML" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <title type="text"><![CDATA[MarkItUp]]></title>
  <sub-title type="text"><![CDATA[Thinking Products...]]></sub-title>
  <authors>
    <author id="2100" date-created="2006-08-10T08:44:35" date-modified="2006-09-04T13:46:38" approved="true" email="notifications@singleuserblog.com">
      <title type="text"><![CDATA[admin]]></title>
    </author>
  </authors>
  <categories>
    <category id="332677d0-64ed-47f7-bf19-639aab02a251" date-created="2005-07-29T03:06:57" date-modified="2005-07-29T03:06:57" approved="true" parentref="3">
      <title type="text"><![CDATA[IBF]]></title>
    </category>
    <category id="1" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:11:09" approved="false" parentref="3">
      <title type="text"><![CDATA[Blogging]]></title>
    </category>
    <category id="09a04594-4f8f-4d8d-b1d4-72d1aaaf4283" date-created="2005-07-21T22:17:22" date-modified="2005-07-29T03:11:21" approved="true" parentref="3">
      <title type="text"><![CDATA[Sharepoint]]></title>
    </category>
    <category id="7" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:11:36" approved="false" parentref="ae6e0ae8-a773-40f6-8215-d018e8a3334b">
      <title type="text"><![CDATA[ProjectDistributor]]></title>
    </category>
    <category id="4" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:11:47" approved="false" parentref="ae6e0ae8-a773-40f6-8215-d018e8a3334b">
      <title type="text"><![CDATA[RegExLib]]></title>
    </category>
    <category id="2" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:12:29" approved="false" parentref="0">
      <title type="text"><![CDATA[Random]]></title>
    </category>
    <category id="5" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:12:40" approved="false" parentref="2">
      <title type="text"><![CDATA[Poems and Quotes]]></title>
    </category>
    <category id="6" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:13:00" approved="false" parentref="0">
      <title type="text"><![CDATA[Rich Client]]></title>
    </category>
    <category id="dd3a77fe-2981-4b10-918e-b0841881146b" date-created="2005-07-27T23:26:37" date-modified="2005-07-29T03:13:13" approved="true" parentref="0">
      <title type="text"><![CDATA[Tools]]></title>
    </category>
    <category id="8" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:13:44" approved="false" parentref="0">
      <title type="text"><![CDATA[Web]]></title>
    </category>
    <category id="3" date-created="2005-01-01T03:00:00" date-modified="2005-07-29T03:39:51" approved="false" parentref="0">
      <title type="text"><![CDATA[Knowledge Products]]></title>
    </category>
    <category id="ae6e0ae8-a773-40f6-8215-d018e8a3334b" date-created="2005-07-27T23:24:51" date-modified="2005-07-29T03:40:01" approved="true" parentref="0">
      <title type="text"><![CDATA[My Projects]]></title>
    </category>
    <category id="00cfc33f-fa73-4a2c-8a55-472368833ee0" date-created="2005-07-26T17:58:18" date-modified="2005-07-30T19:53:03" approved="true" parentref="a6fa585b-e8c1-4153-8815-99ab7888ff46">
      <title type="text"><![CDATA[MSBuild]]></title>
    </category>
    <category id="a6fa585b-e8c1-4153-8815-99ab7888ff46" date-created="2005-07-11T08:32:31" date-modified="2005-07-30T19:53:28" approved="true" parentref="0">
      <title type="text"><![CDATA[Continuous Integration]]></title>
    </category>
    <category id="3846a396-40bb-4ff6-a5b7-7088ec2f1d66" date-created="2005-08-02T21:46:36" date-modified="2005-08-02T21:47:30" approved="true" parentref="0">
      <title type="text"><![CDATA[Sql Server]]></title>
    </category>
    <category id="6d005c2a-634c-4219-9f99-9b7258ed3289" date-created="2005-07-27T23:28:20" date-modified="2005-08-04T00:36:03" approved="true" parentref="bc1e0ae5-7908-452d-a936-f296ba379f23">
      <title type="text"><![CDATA[SUB_Features]]></title>
    </category>
    <category id="dd632fea-284c-4620-9922-840473b72a2b" date-created="2005-08-04T01:42:02" date-modified="2005-08-04T02:11:03" approved="true" parentref="0">
      <title type="text"><![CDATA[Visual Studio]]></title>
    </category>
    <category id="5751cee9-5b20-4db1-93bd-7e7c66208236" date-created="2005-08-26T20:28:41" date-modified="2005-08-26T23:11:05" approved="true" parentref="1">
      <title type="text"><![CDATA[BlogML]]></title>
    </category>
    <category id="8c538a4d-fdba-40c1-a7de-b1c51d237ac9" date-created="2005-09-12T03:26:21" date-modified="2005-09-12T03:26:21" approved="true" parentref="2">
      <title type="text"><![CDATA[Just Writing]]></title>
    </category>
    <category id="bc1e0ae5-7908-452d-a936-f296ba379f23" date-created="2005-07-21T01:55:43" date-modified="2005-07-29T03:12:08" approved="true" parentref="0">
      <title type="text"><![CDATA[SingleUserBlog]]></title>
    </category>
    <category id="d0af0103-f611-4bd8-b627-c3ceaa873838" date-created="2005-09-15T07:04:29" date-modified="2005-09-15T07:04:29" approved="true" parentref="0">
      <title type="text"><![CDATA[Community]]></title>
    </category>
    <category id="fee967b0-b3fa-4538-8768-bf9c70ffb3aa" date-created="2005-09-16T18:16:45" date-modified="2005-09-16T18:16:45" approved="true" parentref="0">
      <title type="text"><![CDATA[Security]]></title>
    </category>
    <category id="00231284-e103-47ca-a56b-fca4723b325a" date-created="2005-09-24T21:45:46" date-modified="2005-09-24T21:45:46" approved="true" parentref="8">
      <title type="text"><![CDATA[WebParts]]></title>
    </category>
    <category id="b4f6f064-8a5b-4008-a2ac-c089e7364d25" date-created="2005-11-12T01:23:53" date-modified="2005-11-12T01:23:53" approved="true" parentref="bc1e0ae5-7908-452d-a936-f296ba379f23">
      <title type="text"><![CDATA[SUB V2 Planning]]></title>
    </category>
    <category id="db527bb5-0e2e-48c4-bb01-7fe1b6d3dad4" date-created="2006-01-14T03:51:56" date-modified="2006-01-14T03:51:56" approved="true" parentref="bc1e0ae5-7908-452d-a936-f296ba379f23">
      <title type="text"><![CDATA[SUB V2 Features]]></title>
    </category>
    <category id="601534f1-b1e9-49a6-8704-0b689a1dd4da" date-created="2006-01-19T20:18:37" date-modified="2006-01-19T20:18:37" approved="true" parentref="8">
      <title type="text"><![CDATA[ASP.NET 2.0]]></title>
    </category>
    <category id="c505e657-3d72-4550-b183-6d8ab9f32634" date-created="2006-01-19T22:51:01" date-modified="2006-01-19T22:51:01" approved="true" parentref="601534f1-b1e9-49a6-8704-0b689a1dd4da">
      <title type="text"><![CDATA[Atlas]]></title>
    </category>
    <category id="768f7edc-c2e0-4998-abce-2f1d0565bb3e" date-created="2006-02-12T09:49:40" date-modified="2006-02-12T09:49:40" approved="true" parentref="0">
      <title type="text"><![CDATA[Home Automation]]></title>
    </category>
    <category id="e64f585a-6ef8-4e86-940d-5279ca56e99d" date-created="2006-02-19T08:01:33" date-modified="2006-02-19T08:01:33" approved="true" parentref="0">
      <title type="text"><![CDATA[Readify]]></title>
    </category>
    <category id="842ae349-1494-451e-b3c0-43c4b5f0f123" date-created="2006-03-23T14:04:08" date-modified="2006-03-23T14:04:08" approved="true" parentref="0">
      <title type="text"><![CDATA[Hockey]]></title>
    </category>
    <category id="abeb483e-2ced-4dc9-93ee-1008368448c0" date-created="2006-04-27T16:11:41" date-modified="2006-04-27T16:11:41" approved="true" parentref="0">
      <title type="text"><![CDATA[Vista]]></title>
    </category>
  </categories>
  <posts>
    <post id="b0e03eec-ab81-4dc4-a69b-374d57cfad5e" date-created="2006-01-07T03:31:32" date-modified="2006-01-07T03:31:32" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=b0e03eec-ab81-4dc4-a69b-374d57cfad5e">
      <title type="text"><![CDATA[Making Web Parts easier to manage]]></title>
      <content type="text">
        <![CDATA[
		<p>
				<strong>Adding Dynamic Content</strong>
		</p>
		<p>I mentioned yesterday that I've been creating numerous different web parts throughout the course of writing my book on the ASP.NET 2.0 Portal Framework.  The web part that I showed in yesterday's article was a part that allowed arbitrary chunks of HTML to be added as content.</p>
		<p>Many of the web parts that are included in the book were inspired from web parts that I needed for the next version of SingleUserBlog - which is built on top of the portal framework.  Having web parts for all of the dynamic content in SingleUserBlog really gives me a lot of flexibility to add dynamic content to my blog and position it wherever I want. <br /> </p>
		<p>
				<strong>Hyperlinks WebPart</strong>
		</p>
		<p>It would be fair to say that most bloggers have many links that are displayed on their blogs.  Heck, even on my simple little blog I have the following groups of links:</p>
		<p>My Websites<br />Blogs I Read<br />Blogs Using SUB<br />My Articles<br />Tools I Use</p>
		<p>For other bloggers that I know of it's common to have as many as twenty different categories of links displayed somewhere on the page of their blog.  For this reason, one of the first web parts that I built was a web part that allowed me to add hyperlinks and have them displayed on the page.  Here's a picture of the web part with links for the blogs that I read:</p>
		<p align="center">
				<img alt="A web part that displays links to the blogs that I read." hspace="0" src="http://localhost:1608/SUBWebV2/Data/Images/blogsireadpart.png " align="baseline" border="1" />
		</p>
		<p>
				<strong>Custom EditorPart for the HyperlinksWebPart</strong>
		</p>
		<p>When I created the HyperlinksWebPart I decided that the data type for storing the custom content should be a custom class that provided a high level of fidelity over how the links are handled.  For example, a user should be able to specify some of following attributes for each hyperlink that they add:</p>
		<ul>
				<li>Display Title 
</li>
				<li>Url 
</li>
				<li>Description (Optional) 
</li>
				<li>Display Order 
</li>
				<li>Whether or not to open in a new page </li>
		</ul>
		<p>Using a complex data type to store the personalization sure provides an easy way to store the data about each hyperlink but complex types do not, by default, get displayed within the property editor when editing a web part.  Thankfully the portal framework makes it very simple to associate custom user interface elements with a web part by simply overriding a method named CreateEditorParts and returning a class that knows how to create an editing interface for a particular type of web part.  By doing this you are able to provide a totally custom solution for managing the data for a web part.  For example, you could display a visual tool such as a map to allow a user to choose which region to display weather information for in a weather web part instead of having to manually type a location name.</p>
		<p>The following image shows the user interface that I created for the Hyperlinks web part so that I could easily add new links or delete existing ones:</p>
		<p align="center">
				<img alt="The custom EditorPart for managing hyperlink data" hspace="0" src="http://localhost:1608/SUBWebV2/Data/Images/customeditorpart.png " align="baseline" border="1" />
		</p>
		<p>The custom EditorPart that I created is titled "Manage Links" and sits within the existing EditorZone.  All of the existing EditorParts that ship with ASP.NET 2.0 can also be displayed within the EditorZone to allow users to manage more "generic" web part properties such as its title, height, width, and chrome type to use.</p>
		<p>As you can see, providing custom EditorParts to manage the data in web parts is a great way to make web parts easier for users to manage by providing fields for each property on the custom data type and allowing users to easily delete existing links.</p>
		<p>Within the next day or so I'll upload a recent build of SUB V2 and supply the authorization credentials so that people can login and have a play with the new web parts to see how they work for real.</p>
]]>
      </content>
      <categories>
        <category ref="b4f6f064-8a5b-4008-a2ac-c089e7364d25" />
        <category ref="00231284-e103-47ca-a56b-fca4723b325a" />
      </categories>
      <attachments>
        <attachment url="http://localhost:1608/subwebv2/data/images/blogsireadpart.png" mime-type="png" embedded="true">[encoded data, 7744 characters]</attachment>
        <attachment url="http://localhost:1608/subwebv2/data/images/customeditorpart.png" mime-type="png" embedded="true">[encoded data, 24516 characters]</attachment>
      </attachments>
    </post>
    <post id="5338c901-c910-4af0-bbca-6ae0067df759" date-created="2006-01-11T20:34:10" date-modified="2006-01-11T20:34:10" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=5338c901-c910-4af0-bbca-6ae0067df759">
      <title type="text"><![CDATA[Adding app-relative items to the Head section of a MasterPage]]></title>
      <content type="text">
        <![CDATA[
		<p>There was an interesting post on one of the <a href="http://aspadvice.com/lists/category.aspx?c=30">ASPNETV2 lists</a> today and yesterday about what is the best way to set an app-relative path for a script block in a Master Page.  Ideally you would just be able to do something like this:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<font face="Courier New" color="#808080" size="2">    &lt;script <br />       language="javascript" <br />       type="text/javascript"<br />       src="&lt;%= Request.ApplicationPath %&gt;/myhelper.js"&gt;&lt;/script&gt;</font>
				</p>
		</blockquote>
		<p>
				<br />Part of the issue here is that you cannot use something like &lt;%= Request.ApplicationPath %&gt; because the &lt;head&gt; tag in the master page is set to runat=server so if you use code blocks within the head section ASP.NET with throw an exception.</p>
		<p>A few people chimed in to suggest doing a simple replace operation on the contents of the head section.  One such suggestion was to do this:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<font face="Courier New" color="#808080" size="2">&lt;head runat="server" id="myHead"&gt;<br />    &lt;script language="javascript" type="text/javascript" src="[MYROOTPATH]/myhelper.js"&gt;&lt;/script&gt;<br />&lt;/head&gt;</font>
				</p>
		</blockquote>
		<p>Then in the Page_Load</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<font face="Courier New" color="#808080" size="2">myHead.InnerText = myHead.InnerText.Replace( "MYROOTPATH", "&lt;rootpath&gt;" );</font>
				</p>
		</blockquote>
		<p>Unfortunately this won't work because you cannot treat the InnerText property as a simple string object.  The way to achieve a result similar to this would be to override the AddParsedSubObject method of control and carry out the parsing logic there.   To do so for the above snippet of HTML would mean doing something like this:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">protected override void AddParsedSubObject(object obj) {<br />    base.AddParsedSubObject(obj);<br />    if (obj is HtmlHead) {<br />        HtmlHead head = (HtmlHead)obj;<br />        foreach (Control ctl in head.Controls) {<br />            if (ctl is LiteralControl) {<br />                LiteralControl ltl = (LiteralControl)ctl;<br />                ltl.Text = ltl.Text.Replace("[MYROOTPATH]", Request.ApplicationPath);<br />            }<br />        }<br />    }<br />}</font>
				</p>
		</blockquote>
		<p>Bertrand Le Roy chimed in to the list and suggested that a better way would be to encapsulate the logic within a control so I tried that out.  My first thought was to create a ScriptControl server control that contained the logic for rendering a script tag, you could then use the server control in the head section of the page like so:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<font face="Courier New" color="#808080" size="2">&lt;wp:ScriptControl Path="~/foo.js" ID="ScriptControl1" runat="server" /&gt;</font>
				</p>
		</blockquote>
		<p>The control that I came up with to achieve this was dirt simple as can be seen in the following snippet of code:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<font face="Courier New" color="#808080" size="2">public class ScriptControl : Control {</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    const string TAG = "&lt;script type=\"text/javascript\" language=\"javascript\" src=\"{0}\" /&gt;";</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    public ScriptControl() { }</font>
				</p>
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">    private string _path;<br />    public string Path {<br />        get { return _path; }<br />        set { _path = value; }<br />    }</font>
				</p>
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">    public override void RenderControl(HtmlTextWriter writer) {</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">        writer.Write(string.Format(TAG, ResolveClientUrl(Path)));<br />        writer.Write(Environment.NewLine);<br />    }<br />}</font>
				</p>
		</blockquote>
		<p>The problem here is that the user is stuck with hard-coded attributes such as "language", "type", and "source".  Ideally the user would add their own attributes and also be able to specify what type of tag it was so that the server control could be re-used for other non-visual elements in the head section of the document that need to reference a specific resource.  The .NET Framework actually provides us with an interface called IAttributeAccessor which allows controls to be the recipients of arbitrary attribute data.  I actually blogged about the IAttributeAccessor interface previously when describing how the GenericWebPart control works (<a href="/Posts/Post.aspx?postId=322871ea-a255-4542-b729-80ffc4d6b352">http://markitup.com/Posts/Post.aspx?postId=322871ea-a255-4542-b729-80ffc4d6b352</a>).</p>
		<p>The control that I arrived at allows you to create elements such as this in the head section of the master page:L</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<font face="Courier New" color="#808080" size="2">&lt;wp:PathControl Path="~/foo.js" ID="PathControl1" runat="server" type="text/javascript" language="javascript" TagType="Script" /&gt;<br /><br />&lt;wp:PathControl Path="~/bar.css" ID="PathControl2" runat="server" type="text/css" media="screen" TagType="Link" /&gt;<br /><br />&lt;wp:PathControl Path="~/Rss.aspx" ID="PathControl3" runat="server" type="application/rss+xml" rel="alternate" title="Rss" TagType="Link" /&gt;</font>
				</p>
		</blockquote>
		<p>
				<br />And here's the code for the PathControl server control:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">public enum TagType : short {<br />    Script,<br />    Link<br />}</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">public class PathControl : Control, IAttributeAccessor {</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    public PathControl() { }</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    public string Path {<br />        get { return ViewState["Path"] as string; }<br />        set { ViewState["Path"] = value; }<br />    }</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    public TagType TagType {<br />        get { return (ViewState["TagType"] == null) ?TagType.Link : (TagType) ViewState["TagType"]; }<br />        set { ViewState["TagType"] = value; }<br />    }</font>
				</p>
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">    Hashtable attribs = new Hashtable();</font>
				</p>
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">    protected override void Render(HtmlTextWriter writer) {<br />        base.Render(writer);</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">        RenderStartTag(writer);</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">        foreach (string key in attribs.Keys) {<br />            writer.WriteAttribute(key, (string)attribs[key]);<br />        }</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">        RenderEndTag(writer);<br />        writer.Write(Environment.NewLine);</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    }</font>
				</p>
				<p>
						<br />
						<font face="Courier New" color="#808080" size="2">    void RenderStartTag(HtmlTextWriter writer) {</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">        if (TagType == TagType.Script) {<br />            writer.Write("&lt;script src=\"" + ResolveClientUrl(Path) + "\"");<br />        } else {<br />            writer.Write("&lt;link href=\"" + ResolveClientUrl(Path) + "\"");<br />        }<br />    }</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">    void RenderEndTag(HtmlTextWriter writer) {</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">        if (TagType == TagType.Script) {<br />            writer.Write("&gt;&lt;/script&gt;");<br />        } else {<br />            writer.Write(" /&gt;");<br />        }<br />    }</font>
				</p>
				<p>
						<font face="Courier New" color="#808080" size="2">
						</font> </p>
				<p>
						<font face="Courier New" color="#808080" size="2">    public string GetAttribute(string key) {<br />        return attribs[key] as string;<br />    }</font>
				</p>
				<p>
						<font face="Courier New">
								<font color="#808080" size="2">    public void SetAttribute(string key, string value) {<br />        attribs[key] = value;<br />    }<br />}</font>
								<br />
						</font>
				</p>
		</blockquote>
]]>
      </content>
      <categories>
        <category ref="8" />
      </categories>
      <comments>
        <comment id="d9eb0c96-8062-45a3-a409-619bc07ffe6b" date-created="2006-01-12T02:20:37" date-modified="2006-01-12T02:20:37" approved="true" user-name="Tracking Handler">
          <title type="text"><![CDATA[Link Listing - January 11, 2006]]></title>
          <content type="text">
            <![CDATA[
  Accessing and Updating Data in ASP.NET 2.0: Data Source 
  Control Basics [Via: ] 
  Adding app-relative...
 found at http://dotnetjunkies.com/WebLog/csteen/archive/2006/01/11/134699.aspx]]>
          </content>
        </comment>
        <comment id="edfe3da5-6516-430c-b1eb-9893746b7fa7" date-created="2006-04-12T20:02:44" date-modified="2006-04-12T20:02:44" approved="true" user-name="Thomas Voelk">
          <title type="text"><![CDATA[Other solution]]></title>
          <content type="text">
            <![CDATA[I stumbled across your page today because I was looking for a solution to the same problem - links in a masterpage. After trying yours (which worked great), I found another one without the use of a control. You can use the ResolveClientUrl-method to create a dynamic link to your stylesheet/library/...

Like this
<link rel="stylesheet" type="text/css" href="<%= ResolveClientUrl("~/styles/style.css") %>" />]]>
          </content>
        </comment>
      </comments>
    </post>
    <post id="ae68899c-ef2d-4be2-aa13-907339918a58" date-created="2006-01-14T09:40:40" date-modified="2006-01-14T09:40:40" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=ae68899c-ef2d-4be2-aa13-907339918a58">
      <title type="text"><![CDATA[This blog is now running SUBV2]]></title>
      <content type="text">
        <![CDATA[
		<p>
		</p>
		<p>
				<a href="/test/default.html">
				</a>
		</p>If this message has popped into your aggregator then I've most certainly done something right because today I changed my blog over to a brand new version of my SingleUserBlog blogging application which I affectionately refer to as SUBV2.  SUBV2 is a significant jump from the previous version in that it's built using ASP.NET 2.0.
<p><strong>Built using ASP.NET 2.0</strong></p><p>Running on top of ASP.NET 2.0 has allowed me to introduce some extremely advanced features while possibly reducing the overall size of the codebase.  Some of the new features include MasterPages and Themes which are used to give the site its look and feel.  Another of the significant changes that have come through using ASP.NET 2.0 are Web Parts and Personalization.  By using these "portal" features I have been able to implement almost all of the content that is visible on this page by using web parts.  To get a feel for how web parts are used on this page, consider the following:</p><ul><li>The Hosted By Orcsweb image is a web part 
</li><li>The Google Search Form is a web part 
</li><li>The Posting Categories list is a web part 
</li><li>Each of the Link Categories on the right are web parts 
</li><li>The Recent Posts listing is a web part 
</li><li>The Horizontal Rule just above the Recent Posts is a web part </li></ul><p>As you can see, the web parts that are included with SUBV2 are a mixture of application web parts (Posting Categories and Recent Posts) as well as functional web parts that allow me to add any arbitrary image, link, or even HTML to the page at will.  The power of web parts is that they can easily be personalized at runtime.  This means that I can move any of the web parts around by simply dragging them with my mouse and placing them to almost anywhere on the page.  I can also add new web parts too.  As an example, I could easily add a new HTML web part that displayed a welcome message to visitors of my blog and place it at the top of each page on the site.  I could even add my own CSS or Javascript too!</p><p><strong>Advanced Portal Framework Features</strong></p><p>In addition to the "out-of-the-box" web part features, this blog also uses some pretty advanced portal customizations - such as a CatalogZone that is displayed in a pop-up dialog (ala Sharepoint V3).  The popup CatalogZone will be used to display web parts that are housed in custom web service galleries. <br /> <br />The blog also features:</p><ul><li>Custom WebPartManager to implement common authorization filter logic 
</li><li>Custom EditorZone to display editor parts in expandible/collapsible regions 
</li><li>Custom WebPartZones to perform custom rendering on web part chrome and to add custom zone verbs to web parts 
</li><li>Custom PersonalizationProvider so that all personalization is stored against a common key (not the page url) so that changes made to a web part are applied right across the portal site </li></ul><p><br /><strong>Migrating my content</strong></p><p>Migrating the content from the previous version of my blog was simple and took me less than twenty minutes.  To migrate the content I opened the administration section of the previous version and saved the blog to BlogML format; then I opened the administration section of this version and imported it.  That's the power of BlogML!  The content that migrated included all of my internal links, attachments and images - so no content was lost at all.</p><p><strong>Making SUBV2 publicly available</strong></p><p>Over the weekend <a href="http://www.paulstovell.net/">Paul Stovell</a> - who is currently running SUBV1 for his blog - will be migrating that blog over to use SUBV2.  During that migration he will write a blog article that explains the steps that are involved in setting up SUBV2 and customizing it with your own MasterPage and Theme.  When he has posted that article I'll upload the source code for SUBV2 to ProjectDistributor so that it is publicly available.  In addition to Paul's article I'll be posting some tutorials to my blog that explain some of the features that are there.</p><p>Over time I'm hoping to build a small community around SUBV2 so that we can share Themes and WebParts.</p>]]>
      </content>
      <categories>
        <category ref="00231284-e103-47ca-a56b-fca4723b325a" />
        <category ref="5751cee9-5b20-4db1-93bd-7e7c66208236" />
        <category ref="bc1e0ae5-7908-452d-a936-f296ba379f23" />
        <category ref="db527bb5-0e2e-48c4-bb01-7fe1b6d3dad4" />
      </categories>
      <comments>
        <comment id="2fc3c24e-e2ad-4edd-80c4-1060bfa73360" date-created="2006-01-15T15:32:17" date-modified="2006-01-15T15:32:17" approved="true" user-name="Ian Thomas">
          <title type="text"><![CDATA[sundry matters]]></title>
          <content type="text">
            <![CDATA[Hi darren
I haven't got even v1 live yet, but I assume you'll be using v2 as an example in your book?
One small thing: I sometimes save blog posts to disk. In this post (maybe all posts), the default name is just "Post" rather than "This blog is now running SUBV2" - can it be chnaged to the latter?]]>
          </content>
        </comment>
        <comment id="ddf26303-b35f-42dc-a3d4-c9897fac0afd" date-created="2006-01-15T15:50:17" date-modified="2006-01-15T15:50:17" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[re: Sundry matters]]></title>
          <content type="text">
            <![CDATA[Thanks for the feedback Ian.  While SUBV2 is not used as an example in my book, I'm certainly using SUBV2 as a "test-bed" for things that I'm writing about.  In the book, the reader actually gets to create a project based on the AdventureWorks database from the ground-up.

Btw: I've just checked in a code change for the V2 source to ensure that the title of the post is used as the title of the page so thanks for that feedback!]]>
          </content>
        </comment>
      </comments>
    </post>
    <post id="32bcc89a-29a3-426e-a08a-5552264f0ca0" date-created="2006-01-17T04:44:29" date-modified="2006-01-17T04:44:29" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=32bcc89a-29a3-426e-a08a-5552264f0ca0">
      <title type="text"><![CDATA[Free copies of VSTS]]></title>
      <content type="text">
        <![CDATA[
		<p>This morning started just like any other morning... I was sitting in my home office drinking coffee and planning my day when a package arrived from UPS.  It's not terribly uncommon for me to receive parcels these days but this one was a different size and shape to the others that I normally receive.</p>
		<p>When I opened the package I discovered that it contained 3 shiny silver cards each of which had a URL engraved on it and a registration number.  It turns out that these cards are invitations that can be given to friends for a 12 month VSTS subscription!  Get that... VSTS free for 12 months!  I thought long and hard before deciding who to give mine to but am happy that, in the end I've given them to people who would love to have VSTS but possibly wouldn't have been able to get it on their own.</p>
		<p>I gave one to a good friend in Sydney who seems to have enjoyed receiving it :-)</p>
		<p>    <a href="http://www.paulstovell.net/Posts/Post.aspx?postId=0846f49b-09e2-4153-a821-f09eb42ddd15">http://www.paulstovell.net/Posts/Post.aspx?postId=0846f49b-09e2-4153-a821-f09eb42ddd15</a></p>
		<p>I was thinking that there might be other MVPs who would struggle to find a really good home for theirs and that it would be good if there was a place where people who really are worthy could nominate themselves as recipients.  Maybe a small clearing house for VSTS invites or something :-)</p>
		<p> </p>
		<p>NOTE: I'm too lazy to take a photo of the cards and post the image here on my blog, but here's a picture of <a href="http://weblogs.asp.net/israelio/archive/2006/01/15/435488.aspx">Ohad</a>'s invites:</p>
		<p>
				<img alt="VSTS Invites" hspace="0" src="http://i-s-r-a-e-l-i.com/images/redcard.jpg" align="baseline" border="1" />
		</p>
]]>
      </content>
      <categories>
        <category ref="dd632fea-284c-4620-9922-840473b72a2b" />
      </categories>
      <attachments />
    </post>
    <post id="1150d124-123b-4d71-95fa-0d5205ec7bb2" date-created="2006-01-18T18:29:51" date-modified="2006-01-18T18:29:51" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=1150d124-123b-4d71-95fa-0d5205ec7bb2">
      <title type="text"><![CDATA[Time Zone Web Service]]></title>
      <content type="text">
        <![CDATA[
		<p>I was chatting with Paul Stovell yesterday about SUB and he asked for a specific feature to do with having posts and comments displayed in his current time zone and not the time zone of the web server.  Specifically he asked:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<br />Well, if you look at my site, it's got the time underneath the post - monday, 7:32pm... that's because it's stored in american time again... but I think even with SUB2 if you store them as universal times, they will be displayed again as american time (ie 10 hours behind)... could you have a Display Timezone or something?</p>
		</blockquote>
		<p>
				<br />Paul's right.  Even if I stored the dates as UTC format, when I got them back out and converted them based on the current time zone they would appear in US date times again.  When we first started to think about solving this problem it seemed simple: create a config setting that allows the admin to enter the UTC offset for the blog and then all DateCreated and DateModified times will use that.  The steps would be: </p>
		<ul>
				<li>store all dates as UTC values 
</li>
				<li>when re-loading dates calculate the difference between the offset and the server GMT offset 
</li>
				<li>apply that difference to the UTC time </li>
		</ul>
		<p>Something that simple would be great and easy to implement - except for daylight time adjustments.  To implement the daylight adjustments would mean that the user would have to enter a value for:</p>
		<ul>
				<li>UTC Offset 
</li>
				<li>Daylight adjustment minutes 
</li>
				<li>Daylight start date 
</li>
				<li>Daylight end date </li>
		</ul>
		<p>It'd all be so much easier if the TimeZone class in the Framework exposed this information.  Luckily for me somebody had already gone to the trouble of exposing this information via API calls and made their code available via this CodeProject article:</p>
		<p>    <a href="http://www.codeproject.com/dotnet/WorldClock.asp">http://www.codeproject.com/dotnet/WorldClock.asp</a></p>
		<p>I very hastily downloaded the code and hacked away at a few prototypes.  As you can see from the CodeProject article I also tacked on a couple of useful helper properties to help work out whether a current time zone is experiencing daylight time or not.</p>
		<p>SUBV2 now uses this logic to store dates in UTC format and convert them to the blog owner's time before they are displayed on the site.</p>
		<p>I've also exposed the some of the TimeZone logic via web services on this site.  You can go here to test them out:</p>
		<p>     <a href="/WebServices/TimeZones.asmx">http://MarkItUp.com/WebServices/TimeZones.asmx</a></p>
		<p>Feel free to play around with them but if you'd like to reference them from an application be sure to contact me first so that I can advise you of any changes or if I plan to move them to a new location.  Over time I'll probably issue keys to access the service so that I can formally keep track of who is using them.  If you want to try it out you'll have to hit this method first to get a list of the time zone names so that you can pass them to the other methods:</p>
		<p>     <a href="/WebServices/TimeZones.asmx?op=GetTimeZoneNames">http://markitup.com/WebServices/TimeZones.asmx?op=GetTimeZoneNames</a></p>
		<p> </p>
]]>
      </content>
      <categories>
        <category ref="8" />
        <category ref="db527bb5-0e2e-48c4-bb01-7fe1b6d3dad4" />
      </categories>
      <comments>
        <comment id="1efccca1-2e31-4e73-b451-1328c1e276fa" date-created="2006-01-18T20:47:51" date-modified="2006-01-18T20:47:51" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[Test Comment]]></title>
          <content type="text"><![CDATA[Just testing to see whether the TimeZone stuff is working... I'm adding this comment at 4:47 Australian Eastern Daylight Time]]></content>
        </comment>
        <comment id="8ea1c0dd-1684-4c6e-8190-f03f80e75573" date-created="2006-01-19T10:17:54" date-modified="2006-01-19T10:17:54" approved="true" user-name="Michael Gibbs">
          <title type="text"><![CDATA[Link to your webservice 404s...]]></title>
          <content type="text"><![CDATA[Going to the link (http://MarkItUp.com/WebServices/TimeZones.aspx) on this post returns a 404 error...]]></content>
        </comment>
        <comment id="7c0e1111-b2dc-4aad-a3db-5c5dca23279a" date-created="2006-01-19T11:14:32" date-modified="2006-01-19T11:14:32" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[Woops]]></title>
          <content type="text">
            <![CDATA[That link should have pointed to an ASMX file, *not* an ASPX file.  Fixed.

Thanks!]]>
          </content>
        </comment>
        <comment id="4500ff31-1010-42f5-9546-ce206b4daf67" date-created="2006-01-27T17:17:52" date-modified="2006-01-27T17:17:52" approved="true" user-name="Paul Jones">
          <title type="text"><![CDATA[Source]]></title>
          <content type="text"><![CDATA[Any chance on getting the source for this? I need to run this on a closed network (no access to Internet) so using this web service is not an option. I will give you the credit of course...]]></content>
        </comment>
        <comment id="8e0b543d-52f1-4aa1-9e2c-0040b17506e9" date-created="2006-01-27T20:04:36" date-modified="2006-01-27T20:04:36" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[Sure thing.]]></title>
          <content type="text">
            <![CDATA[I'll upload a working sample to my ProjectDistributor account over the weekend and blog a link to it when I do.

Cheers!
- Darren Neimke]]>
          </content>
        </comment>
        <comment id="82ea0f69-cc3e-4329-9281-7a660661eb05" date-created="2006-01-29T14:48:25" date-modified="2006-01-29T14:48:25" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[The web service has been uploaded]]></title>
          <content type="text">
            <![CDATA[Check this post:

http://markitup.com/Posts/Post.aspx?postId=e1006d1b-1b51-4929-85e2-d4f31d1f79ff]]>
          </content>
        </comment>
      </comments>
    </post>
    <post id="72efe029-f023-4964-aa8d-f65c5668edd8" date-created="2006-01-19T02:01:04" date-modified="2006-01-19T02:01:04" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=72efe029-f023-4964-aa8d-f65c5668edd8">
      <title type="text"><![CDATA[Bubbles]]></title>
      <content type="text">
        <![CDATA[
		<a href="http://www.usatoday.com/money/perfi/housing/2006-01-17-real-estate-usat_x.htm?csp=34">43% of first-time home buyers put no money down</a>... hrmm, the same 43% who will finally have enough equity to <a href="http://www.wired.com/news/technology/0,70034-0.html?tw=rss.index">start buying stocks in 2011</a> no doubt!]]>
      </content>
      <categories>
        <category ref="2" />
      </categories>
    </post>
    <post id="52252561-f83d-4463-82f0-769fce82fd82" date-created="2006-01-19T12:21:58" date-modified="2006-01-19T12:21:58" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=52252561-f83d-4463-82f0-769fce82fd82">
      <title type="text"><![CDATA[Displaying dates and times in a local users time zone]]></title>
      <content type="text">
        <![CDATA[
		<p>
				<a href="/Posts/Post.aspx?postId=1150d124-123b-4d71-95fa-0d5205ec7bb2">Yesterdy I wrote about the TimeZones web service</a> that I've added to this site and today I'll further explain the need for the web service.  To start, let's take a look at the problem of dates and break it into 2 segments: The date value and the format of the date value.</p>
		<p>
				<strong>Formatting a culture aware date.</strong>
		</p>
		<p>Let's say that you are from the US and you visit my site.  On reading an article (and after sighing that this guy doesn't know what he's talking about) you notice that the time that page says that the article was written on 18/1/2006.  Hrmm, you think to yourself... what is the 18th month again?  This is of course because in the US, dates are formatted as mm/dd/yyyy whereas in Australia here they are formatted as dd/mm/yyyy.</p>
		<p>The answer to fixing the formatting of dates is thankfully quite simple.  Rather than formatting the date for a specific culture you can dynamically read the culture for the current user from the accept-languages array that is passed along with the head section of the request.  To do this you simply set the culture of the current thread when the request begins and then delegate all of the formatting of dates and number strings to the framework - in other words, it just works!  Here's the code that you can place in your application's BeginRequest method to achieve this outcome:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>void Application_BeginRequest(Object sender, EventArgs e) {<br />    try {<br />        if (Request.UserLanguages.Length &gt; 0) {<br />            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);<br />            Thread.CurrentThread.CurrentUICulture = new CultureInfo(Request.UserLanguages[0]);<br />        }<br />    } catch (Exception ex) {<br />        PublishException(ex);<br />    }<br />}</p>
		</blockquote>
		<p>
				<br />SUB has that code in its startup so go ahead and try it out.  In Internet Explorer open up Tools | Options and choose "Languages" from the General tab.  In there you can add language or change the order of your language preferences.  Change it by adding Arabic or Chinese as your first preference and refresh the browser to see how the dates for this article are formatted.</p>
		<p>
				<br />
				<strong>Setting the correct date value</strong>
		</p>
		<p>OK, so formatting culture aware dates is a breeze.  Just a couple of lines of code.  But what about storing the value that is used?  That's somewhat harder.  Here's a scenario:</p>
		<p>Your website is hosted on a webserver that is located on the west coast of the US and you are currently living in Australia.  You use the web interface that is supplied with your blogging software to add a new article at 8:00am Australian time which is about 1:00pm Pacific time.  A time difference of 19 hours.</p>
		<p>The next week, the people hosting your website move to Greenland and so when you post your next article - again at 8:00am Australian time, the time on the server is now 6:00pm on the previous day.  A time difference of 14 hours.</p>
		<p>Finally, daylight time ends in Australia and you post another article at 8:00am Australian time which is now 7:00pm in Greenland.  A difference of 13 hours.</p>
		<p>So how would you write a single piece of code that would always know to display the published times of your articles in Australian time?  One way would be to use javascript on the client and pass through the clients time to the server and use that.  It would work but it's cumbersome.</p>
		<p>The better way - and the way that it is done for SUB - is to immediately store all dates in UTC time at the time that they are entered.  Working out the current UTC time is a no brainer:</p>
		<p>
				<br />     currentArticle.DateCreated = DateTime.UTCNow ;<br />     currentArticle.Modified = DateTime.UTCNow ;</p>
		<p>The reason for storing the dates in UTC time is that it's easy to work with because every country already has a pre-existing way of defnining an offset from that time to work back to their own local time - the timezone difference.</p>
		<p>Now that the time is stored as UTC time it can simply be converted to the local time of a given time zone as soon as it is reloaded from storage.  In the case of SUB the logic for doing that looks like this:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<br />DateTime dt1 = DateTime.Parse(node.Attributes["dateCreated"].Value);<br />DateTime dt2 = DateTime.Parse(node.Attributes["dateModified"].Value);                <br />                <br />TimeZoneInformation info = TimeZoneInformation.FromName(<br />    BlogConfigurationSettings.TimeZoneName<br />    );</p>
				<p>
						<br />DateTime utc1 = info.FromUniversalTime(dt1);<br />DateTime utc2 = info.FromUniversalTime(dt2);</p>
				<p>this.DateCreated = utc1;<br />this.DateModified = utc2;</p>
		</blockquote>
		<p>
				<br />See that the UTC times are pulled from the XML storage and then the TimeZoneInformation class is spun up for the time zone that the blog has been configured to use.  Then, using that class (which itself uses the underlying Windows API's) the UTC time can easily be converted to the timezone that the blog has been configured to use.</p>
		<p>When the data is stuffed back into storage - such as when it is edited - the TimeZoneInformation class is again used to convert the local time back to UTC time as shown in the next snippet:</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<br />TimeZoneInformation info = TimeZoneInformation.FromName(<br />    BlogConfigurationSettings.TimeZoneName<br />    );</p>
				<p>DateTime utc1 = info.ToUniversalTime(this.DateCreated);<br />DateTime utc2 = info.ToUniversalTime(this.DateModified);</p>
				<p>
						<br />attr = node.OwnerDocument.CreateAttribute("dateCreated");<br />attr.Value = FormatDateTime(utc1);<br />node.Attributes.Append(attr);</p>
				<p>attr = node.OwnerDocument.CreateAttribute("dateModified");<br />attr.Value = FormatDateTime(utc2);<br />node.Attributes.Append(attr);<br /></p>
		</blockquote>
		<p dir="ltr">So when you read this article and you see that it was posted on 19/01/2006 at 8:19:10 AM (if your browser language is Australian anyway) you will know that I wrote it on the morning of the 19th January and not at 1:00am on the morning of the 20th January as would be the case if I was using the server times to store dates.</p>
]]>
      </content>
      <categories>
        <category ref="8" />
        <category ref="db527bb5-0e2e-48c4-bb01-7fe1b6d3dad4" />
      </categories>
    </post>
    <post id="98f7c2a8-e39a-4ce0-ade5-5857b121e6e4" date-created="2006-01-19T20:18:59" date-modified="2006-01-19T20:18:59" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=98f7c2a8-e39a-4ce0-ade5-5857b121e6e4">
      <title type="text"><![CDATA[Dynamic URL Rewriter for ASP.NET 2.0]]></title>
      <content type="text">
        <![CDATA[
		<p>Seen via <a href="http://weblogs.asp.net/scottgu/archive/2006/01/18/435870.aspx">Scott Guthrie's blog</a> is a cool HttpModule that you can use to perform dynamic URL rewrites using regular expressions.  There's a UrlMapper that comes out-of-the-box with ASP.NET 2.0 but it doesn't allow for dynamic rewrites.  Here is the link to the dynamic mapper:</p>
		<p>     <a href="http://www.urlrewriting.net/Config.aspx?Language=en&amp;AspxAutoDetectCookieSupport=1">http://www.urlrewriting.net/Config.aspx?Language=en&amp;AspxAutoDetectCookieSupport=1</a></p>
		<p>This will come in handy if you are using SUB but you still want your old links to work.  For example, let's say that you were using .Text 0.95 which would format your post links like so:</p>
		<p>     <a href="http://yourdomain.com/posts/9999.aspx">http://yourdomain.com/posts/9999.aspx</a></p>
		<p>When you migrate to SUB this link will become:</p>
		<p>     <a href="http://yourdomain.com/posts/post.aspx?postId=9999">http://yourdomain.com/posts/post.aspx?postId=9999</a></p>
		<p>Which means that anyone who has links to your old posts will find them missing.  Not anymore!  Add a reference to the UrlRewritingNet.UrlRewriter and add the following configuration and you are away!</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>
						<br />&lt;urlrewritingnet<br />  rewriteOnlyVirtualUrls="true" <br />  contextItemsPrefix="QueryString" <br />  compileRegex="true"<br />  xmlns="<a href="http://www.urlrewriting.net/schemas/config/2006/01">http://www.urlrewriting.net/schemas/config/2006/01</a>" &gt;<br />  <br />  &lt;rewrites&gt;<br />    &lt;add virtualUrl="^~/Posts/(.*).aspx" <br />         rewriteUrlParameter="ExcludeFromClientQueryString" <br />         destinationUrl="~/posts/post.aspx?postId=$1"<br />         ignoreCase="false"/&gt;<br />  &lt;/rewrites&gt;<br />  <br />&lt;/urlrewritingnet&gt;</p>
		</blockquote>
]]>
      </content>
      <categories>
        <category ref="601534f1-b1e9-49a6-8704-0b689a1dd4da" />
      </categories>
    </post>
    <post id="d16a3aed-1dec-43e7-b20c-e6bcee95f8b3" date-created="2006-01-19T22:51:27" date-modified="2006-01-19T22:51:27" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=d16a3aed-1dec-43e7-b20c-e6bcee95f8b3">
      <title type="text"><![CDATA[Atlas Samples]]></title>
      <content type="text">
        <![CDATA[
		<p>If, like me you've been trying to keep abreast of the moving target which is "Atlas" you'll be excited to know that Nikhil has posted a bunch of recent samples that run against the Dec CTP of Atlas.  You can grab the details here:</p>
		<p>    <a href="http://www.nikhilk.net/Entry.aspx?id=104">http://www.nikhilk.net/Entry.aspx?id=104</a></p>
		<p>Highly recommended!</p>
]]>
      </content>
      <categories>
        <category ref="c505e657-3d72-4550-b183-6d8ab9f32634" />
      </categories>
    </post>
    <post id="3f319483-f068-45d8-81b3-ccbf5459ebaf" date-created="2006-01-20T22:59:38" date-modified="2006-01-20T22:59:38" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=3f319483-f068-45d8-81b3-ccbf5459ebaf">
      <title type="text"><![CDATA[Building ASP.NET 2.0 Web Sites Using Web Standards]]></title>
      <content type="text">
        <![CDATA[
		<p>I found this link via <a href="http://haacked.com">Phil's blog</a>:</p>
		<p>    <a href="http://msdn.microsoft.com/asp.net/reference/design/default.aspx?pull=/library/en-us/dnaspp/html/aspnetusstan.asp">Building ASP.NET 2.0 Web Sites Using Web Standards</a></p>
		<p>It is an article by Stephen Walther (geez that guy writes a lot of stuff) that covers all of the web standards "hooks" in ASP.NET 2.0.  There's a heap of little treasures in there.  For example I can honestly say that today is the first time that I'd heard of the <strong>GenerateEmptyAlternateText</strong> property for the Image web control.</p>
		<p>    </p>
]]>
      </content>
      <categories>
        <category ref="601534f1-b1e9-49a6-8704-0b689a1dd4da" />
      </categories>
    </post>
    <post id="6d2a4b70-0bba-49d0-9bc7-b0b071bd89f6" date-created="2006-01-21T01:48:14" date-modified="2006-01-21T01:48:14" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=6d2a4b70-0bba-49d0-9bc7-b0b071bd89f6">
      <title type="text"><![CDATA[Geek Dinner in Canberra - Wednesday, February the 8th]]></title>
      <content type="text">
        <![CDATA[
		<p>After reading <a href="http://codebetter.com/blogs/geoff.appleby/archive/2006/01/20/136817.aspx">Geoff's announcement</a> of the next Geek dinner I thought that I'd better write something just as witty so I started analyzing what he'd written and planning an equally witty response.  Then I remembered an old quote and thought better of it.</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>"Analyzing humor is like dissecting a frog. Few people are interested, and the frog dies of it."<br />- E.B.White (1899—1985).  </p>
		</blockquote>
		<p>OK, so here's my version of the announcement.  <strong>Geek Dinner in Canberra on the evening of Wednesday, February the 8th</strong>.  F*ck knows where at this stage :-) but Geoff and I will "collaborate" on that one and blog it next week. At this stage I imagine that it will probably be at Babars in Civic again because of its centrality.</p>
		<p>And on that note I'll end with another quote...</p>
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p>"It is a good thing for an uneducated man to read books of quotations."    — Winston Churchill. <br /></p>
		</blockquote>
]]>
      </content>
      <categories>
        <category ref="d0af0103-f611-4bd8-b627-c3ceaa873838" />
      </categories>
      <comments>
        <comment id="72328569-c1f0-4a3d-9dad-53cd56a1928c" date-created="2006-05-03T01:30:11" date-modified="2006-05-03T01:30:11" approved="true" user-name="Tracking Handler">
          <title type="text"><![CDATA[Canberra Geek Dinner and Non-Geek Survival guide]]></title>
          <content type="text">
            <![CDATA[
        Geoff and Darren have set the date Wednesday, Feb 8th (but no venue yet - probably Babar in...
 found at http://localhost/cs/blogs/sample_weblog/archive/2006/01/24/100.aspx]]>
          </content>
        </comment>
      </comments>
    </post>
    <post id="02170991-7a00-4aa3-a63e-f6b6d71c9d3b" date-created="2006-01-21T16:04:47" date-modified="2006-01-21T16:04:47" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=02170991-7a00-4aa3-a63e-f6b6d71c9d3b">
      <title type="text"><![CDATA[This is the best blonde joke ever.]]></title>
      <content type="text">
        <![CDATA[
		<p>This is a seriously funny joke...</p>
		<p>     <a href="http://haacked.com/archive/2006/01/20/BestBlondeJokeEver.aspx"><font color="#355ea0">This is the best blonde joke ever</font></a>.</p>
]]>
      </content>
      <categories>
        <category ref="2" />
      </categories>
      <comments>
        <comment id="845328be-7987-49d9-80b3-a296eb86b135" date-created="2006-01-21T22:58:47" date-modified="2006-01-21T22:58:47" approved="true" user-name="RockyH" user-url="http://www.rockyh.net">
          <title type="text"><![CDATA[Excellent!!!]]></title>
          <content type="text"><![CDATA[I have to admit, I've heard a LOT of blond jokes, but that one has to take the cake. Only in the blgosphere can such a masterpiece be seen. ]]></content>
        </comment>
        <comment id="1f977b58-2e6a-4c77-b052-bdecdeaa4cb3" date-created="2006-01-22T01:16:34" date-modified="2006-01-22T01:16:34" approved="true" user-name="JosephCooney" user-url="http://jcooney.net">
          <title type="text"><![CDATA[Grrrr....]]></title>
          <content type="text"><![CDATA[Oh, no....not you TOO]]></content>
        </comment>
        <comment id="1916e880-50df-49ba-89b4-53f1f47934b8" date-created="2006-01-22T01:25:13" date-modified="2006-01-22T01:25:13" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[The blonde joke thing]]></title>
          <content type="text">
            <![CDATA[Rock...

Yeah, the blogsphere just seems to have a knack for producing these gems.

Joseph...

Seriously, I had never heard of that joke until today.  I laughed my ass off when I finally *got* it.


]]>
          </content>
        </comment>
      </comments>
    </post>
    <post id="25c830a6-f12b-46e2-a3e5-3251b0071ac0" date-created="2006-01-24T19:58:04" date-modified="2006-01-24T19:58:04" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=25c830a6-f12b-46e2-a3e5-3251b0071ac0">
      <title type="text"><![CDATA[What the hell happened to the computer business?]]></title>
      <content type="text"><![CDATA[I was reading the Manning Press blog today and found an article which discusses the decline int the market for IT books (and also business books).  The blog article mentions a book that they have which was written to answer the question of:  Why Companies Will Spend Less to Get More from Information Technology.<br /><br /><p><a href="http://www.amazon.com/exec/obidos/ASIN/1932394133/forestlakewebser"><img src="http://images.amazon.com/images/P/1932394133.01.MZZZZZZZ.jpg" /></a></p><p>The book claims to explain:</p><ul><li>What is happening to the Computer Industry </li><li>How to respond to the change - whether you are an IT Vendor or an IT User</li></ul><p>Sounds like an interesting read.</p>]]></content>
      <categories>
        <category ref="2" />
      </categories>
      <attachments />
    </post>
    <post id="91a500c0-06dc-4f7c-9723-86dd68ddf180" date-created="2006-01-27T13:13:09" date-modified="2006-01-27T13:13:09" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=91a500c0-06dc-4f7c-9723-86dd68ddf180">
      <title type="text"><![CDATA[SUB V2 - First Release]]></title>
      <content type="text">
        <![CDATA[
		<p>OK, so I've just uploaded the source code for this blog (SUB V2) to ProjectDistributor.  To download it go here:</p>
		<p>     <a href="http://projectdistributor.net/Projects/Project.aspx?projectId=182">http://projectdistributor.net/Projects/Project.aspx?projectId=182</a></p>
		<p>The biggest features in this release are that the blog uses MasterPages, Themes, and has a pretty cool WebPart framework which is coming into shape.</p>
		<p>To run the blog just open the solution file and do a build.  You also need to configure a database to use the ASPNET SQL Server tables because this version uses Profile to store some user information.</p>
		<p>Aside from using the major new ASP.NET 2.0 features such Themes, MaserPages, WebPart, Profile etc, and the new runtime feature - Generics - it's a parity release with the ASP.NET 1.1 version of SingleUserBlog.  Here is a screenshot of the features that will appear in the next version (Iteration 1) of the software:</p>
		<p align="center">
				<img alt="SUB V2 features that are coming soon" hspace="0" src="http://localhost:1608/SUBWebV2/Data/Images/subv2featurescomingsoon.png " align="baseline" border="1" />
		</p>
]]>
      </content>
      <categories>
        <category ref="601534f1-b1e9-49a6-8704-0b689a1dd4da" />
        <category ref="bc1e0ae5-7908-452d-a936-f296ba379f23" />
        <category ref="db527bb5-0e2e-48c4-bb01-7fe1b6d3dad4" />
      </categories>
      <attachments>
        <attachment url="http://localhost:1608/subwebv2/data/images/subv2featurescomingsoon.png" mime-type="png" embedded="true">[encoded data, 53160 characters]</attachment>
      </attachments>
    </post>
    <post id="ec1e4b20-cc98-4700-bf82-ff07e1cd619f" date-created="2006-01-27T19:16:35" date-modified="2006-01-27T19:16:35" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=ec1e4b20-cc98-4700-bf82-ff07e1cd619f">
      <title type="text"><![CDATA[Apparently SUB V2 is not very hard to Theme :-)]]></title>
      <content type="text">
        <![CDATA[
		<p>Paul Stovell has installed SUB V2 for his blog and has written a post about how he went about personalizing the theme.  </p>
		<p>    <a href="http://www.paulstovell.net/Posts/Post.aspx?postId=1348228b-da36-43d9-844b-e70fabf4c8ad">http://www.paulstovell.net/Posts/Post.aspx?postId=1348228b-da36-43d9-844b-e70fabf4c8ad</a></p>
		<p>To quote a very enthusiastic sounding Paul:</p>
		<em>
				<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
						<p>
								<br />...this new SingleUserBlog is amazingly customisable. The first time I put this site up with SingleUserBlog 1.0, I spent hours slaving over a hot IDE, changing the layout to get it just how I wanted. It was a case of opening each ASPX page, editing the code, and crossing my fingers and hoping it would compile. <br /><br />But SingleUserBlog 2.0, put simply, rocks! The only thing I had to do was add a new Master Page (PaulStovell.master), a new Theme folder (App_Themes/PaulStovell), and drag and drop my old stylesheet. Then I played with the master page for a total of about 20 minutes, rearranging the elements to suit my layout, and tada! Instant customisability.<br /></p>
				</blockquote>
		</em>
		<p>I'll be adding Paul's .master file and Theme files to the base install of SUB so that users will now have a choice.</p>
]]>
      </content>
      <categories>
        <category ref="bc1e0ae5-7908-452d-a936-f296ba379f23" />
      </categories>
      <comments>
        <comment id="53a76dfd-9165-4582-8118-094cb8ec6a69" date-created="2006-01-28T02:37:04" date-modified="2006-01-28T02:37:04" approved="true" user-name="anon">
          <title type="text"><![CDATA[downloading subv2]]></title>
          <content type="text">
            <![CDATA[your download file is corrupt and won't decompress.
looks good in theory :)]]>
          </content>
        </comment>
        <comment id="f33fe64b-4eac-4d9d-8ede-a0229f980466" date-created="2006-01-28T15:38:58" date-modified="2006-01-28T15:38:58" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[Fixed]]></title>
          <content type="text"><![CDATA[I've fixed the download on the site.  Not sure what the problem was because the zip opened fine before I uploaded it.]]></content>
        </comment>
      </comments>
    </post>
    <post id="e1006d1b-1b51-4929-85e2-d4f31d1f79ff" date-created="2006-01-29T12:33:13" date-modified="2006-01-29T12:33:13" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=e1006d1b-1b51-4929-85e2-d4f31d1f79ff">
      <title type="text"><![CDATA[Time Zone Web Service]]></title>
      <content type="text">
        <![CDATA[
		<p>I've uploaded a working demo of the TimeZone web service which you can find here:</p>
		<p>    <a href="http://projectdistributor.net/Projects/Project.aspx?projectId=183">http://projectdistributor.net/Projects/Project.aspx?projectId=183</a></p>
		<p> </p>
]]>
      </content>
      <categories>
        <category ref="8" />
      </categories>
    </post>
    <post id="0be1d98c-016a-4e83-956c-85ccc801edac" date-created="2006-04-26T17:05:54" date-modified="2006-04-26T17:05:54" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=0be1d98c-016a-4e83-956c-85ccc801edac">
      <title type="text"><![CDATA[Captain of my soul]]></title>
      <content type="text">
        <![CDATA[
		<p>
				<em>Out of the night that covers me,<br />Black as a Pit from pole to pole,<br />I thank whatever gods may be<br />For my unconquerable soul.<br /><br />In the fell clutch of circumstance<br />I have not winced nor cried aloud,<br />Under the bludgeonings of chance<br />My head is bloody, but unbowed.<br /><br />Beyond this place of wrath and tears<br />Looms but the horror of the shade,<br />And yet the menace of the years<br />Finds, and shall find me, unafraid.<br /><br />It matters not how straight the gate,<br />How charged with punishments the scroll,<br />I am the master of my fate:<br />I am the Captain of my soul.</em>
		</p>
		<p>- Willian Ernest Henley (1875)</p>
]]>
      </content>
      <categories>
        <category ref="5" />
      </categories>
    </post>
    <post id="cea2b1b2-bf2c-437b-ba4c-3b0591904373" date-created="2006-04-27T16:12:13" date-modified="2006-04-27T16:12:13" approved="true" post-url="http://localhost:1608/SUBWebV2/Posts/Post.aspx?postId=cea2b1b2-bf2c-437b-ba4c-3b0591904373">
      <title type="text"><![CDATA[Vista UAP]]></title>
      <content type="text">
        <![CDATA[
		<p>It appears that the uproar that occurred during my discussion on Vista UAP on the weekend is nothing compared with other discussions that have been taking place around the web.  Tonight Joseph sent me a link which actually explains how to turn off "those annoying security warning dialogs".  Well it doesn't actually turn them off, it just allows Administrator users to run as Admin. </p>
		<p>    <a href="http://www.codinghorror.com/blog/archives/000571.html">http://www.codinghorror.com/blog/archives/000571.html</a></p>
		<p>In a nutshell:</p>
		<blockquote>
				<i>[..] even if you are logged in as Administrator, you're not getting Adminstrator rights. There's a way to turn this feature off by the way: 
<p></p><ul><li>Run gpEdit.msc 
</li><li>Go to: Computer Configuration | Windows Settings | Security Settings | Local Policies | Security Options 
</li><li>User Account Control: Run all users including Administrators as standard users - Disable 
</li><li>User Account Control: Behavior of the elevation prompt - No Prompt </li></ul><p>Then log off and log back on. </p></i>
		</blockquote>
		<p>I'm sure that this will make many people very happy and others.... well, let's just say that you can't please all of the people all of the time.  As for me: I think that this time I will actually attempt to make good my promise of running as a Standard User.</p>
]]>
      </content>
      <categories>
        <category ref="abeb483e-2ced-4dc9-93ee-1008368448c0" />
      </categories>
      <comments>
        <comment id="39b6fe5c-968b-4dbb-a036-fc0b05f2e8ed" date-created="2006-04-29T14:11:40" date-modified="2006-04-29T14:11:40" approved="true" user-name="Tracking Handler">
          <title type="text"><![CDATA[How to turn off UAP?]]></title>
          <content type="text">
            <![CDATA[
 found at http://notgartner.com/posts/4154.aspx]]>
          </content>
        </comment>
        <comment id="5d17f24a-6f44-498a-a756-9d3fb44a2fc7" date-created="2006-04-30T04:26:38" date-modified="2006-04-30T04:26:38" approved="true" user-name="JosephCooney" user-url="http://jcooney.net">
          <title type="text"><![CDATA[UAP]]></title>
          <content type="text"><![CDATA[Just to be fair, I'm not advocating doing this - I just know you copped a bit of flack over this at codecamp. I think the problem with this isn't UAP, its apps requiring administrative privileges to run.]]></content>
        </comment>
        <comment id="7211c4e6-9358-4ebe-a097-7bf3862ad020" date-created="2006-04-30T04:49:41" date-modified="2006-04-30T04:49:41" approved="true" user-name="Darren Neimke" user-url="http://MarkItUp.com">
          <title type="text"><![CDATA[Apps that require admin privileges]]></title>
          <content type="text">
            <![CDATA[I agree Joseph.  I think that when you try to run under UAP that you start to get some insight of which teams at Microsoft do not run that way.  

I hate to say this but, because of how reliant we are on MS produced software, the trend to running as Standard User will have to come from Microsoft first.]]>
          </content>
        </comment>
      </comments>
    </post>
  </posts>
</blog>