


<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fresh Click Media &#187; .NET</title>
	<atom:link href="http://www.freshclickmedia.com/blog/category/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.freshclickmedia.com</link>
	<description></description>
	<lastBuildDate>Wed, 17 Mar 2010 18:27:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>5 things you may not know about ASP.NET</title>
		<link>http://www.freshclickmedia.com/blog/2009/03/5-things-you-may-not-know-about-aspnet/</link>
		<comments>http://www.freshclickmedia.com/blog/2009/03/5-things-you-may-not-know-about-aspnet/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 12:17:55 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/?p=138</guid>
		<description><![CDATA[Since its release in early 2002, Microsoft's ASP.NET platform has gone from strength to strength.  Despite its strong uptake from Microsoft-centric software houses, there may be a few people who have hesitated in adopting ASP.NET for their web development platform.  Here I present some things you might not know about ASP.NET.  Perhaps it'll encourage you to take a look at it.

<h3>Cost</h3>
There once was a time when the standard IDE for developing ASP.NET apps, Visual Studio, was prohibitively expensive for the average Joe.  In late 2007, Microsoft released its first versions of 'Express' software, aimed at students and hobbyists.  Though Express incarnations have fewer features than their full version cousins, they do offer the possibility of exploring ASP.NET.  The Microsoft website offers a <a href="http://www.microsoft.com/express/vwd/">download page for Visual Web Developer 2008 Express Edition</a>. An express version of SQL Server is also available, and can be downloaded from the <a href="http://www.microsoft.com/express/sql/">SQL Server 2008 download page</a>.

<h3><abbr title="Model View Controller">MVC</abbr> Support</h3>
The MVC pattern is an established and well-recognised way of building web applications, and is familiar to <abbr title="Ruby on Rails">RoR</abbr>, Java and PHP developers.  For many years, MVC was not available as a standard approach to developing ASP.NET websites, but Microsoft has recognised the deficiency and have (at the time of writing) released version 1.0 Release Candidate of ASP.NET MVC.  The release has had a mixed response from the ASP.NET community, many of whom are used to the traditional code-behind model.  Despite the inevitable squabbles as to which way is best, many have welcomed the MVC approach for its separation of concerns and finer control over JavaScript and markup.  To find out more about the release candidate, head over to <a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx">Scott Guthrie's blog post</a>.

<h3>Learning Resources</h3>  
A big advantage for anybody learning a new technology is the wealth of learning material that is available.  Although you can rely on a large number of books, the <a href="http://www.asp.net/learn">ASP.NET learn</a> website contains many videos on both traditional and MVC ASP.NET as well as data access.

<h3>Intrinsic jQuery Support</h3>
The lightweight open source JavaScript library that's taken the web by storm is now fully supported by Microsoft.  As well as <a href="http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx">full intellisense support in Visual Studio</a>, Microsoft will be using the library as-is, without forking or changing the code from the main jQuery branch.  What's more, Microsoft will be using jQuery as a basis for future ASP.NET and ASP.NET AJAX features.  I feel this counters the argument of Microsoft not supporting open-source software.

<h3>Career Prospects</h3>
Microsoft's ubiquity means that learning ASP.NET and supporting technologies will do no harm to your career prospects.  <a href="http://www.cwjobs.co.uk/Content/PermanentDeveloperDemand.html">.NET skills are ranked as some of the most in-demand in the UK</a>.  ]]></description>
			<content:encoded><![CDATA[<p>Since its release in early 2002, Microsoft&#8217;s ASP.NET platform has gone from strength to strength.  Despite its strong uptake from Microsoft-centric software houses, there may be a few people who have hesitated in adopting ASP.NET for their web development platform.  Here I present some things you might not know about ASP.NET.  Perhaps it&#8217;ll encourage you to take a look at it.</p>
<h3>Cost</h3>
<p>There once was a time when the standard IDE for developing ASP.NET apps, Visual Studio, was prohibitively expensive for the average Joe.  In late 2007, Microsoft released its first versions of &#8216;Express&#8217; software, aimed at students and hobbyists.  Though Express incarnations have fewer features than their full version cousins, they do offer the possibility of exploring ASP.NET.  The Microsoft website offers a <a href="http://www.microsoft.com/express/vwd/">download page for Visual Web Developer 2008 Express Edition</a>. An express version of SQL Server is also available, and can be downloaded from the <a href="http://www.microsoft.com/express/sql/">SQL Server 2008 download page</a>.</p>
<h3><abbr title="Model View Controller">MVC</abbr> Support</h3>
<p>The MVC pattern is an established and well-recognised way of building web applications, and is familiar to <abbr title="Ruby on Rails">RoR</abbr>, Java and PHP developers.  For many years, MVC was not available as a standard approach to developing ASP.NET websites, but Microsoft has recognised the deficiency and have (at the time of writing) released version 1.0 Release Candidate of ASP.NET MVC.  The release has had a mixed response from the ASP.NET community, many of whom are used to the traditional code-behind model.  Despite the inevitable squabbles as to which way is best, many have welcomed the MVC approach for its separation of concerns and finer control over JavaScript and markup.  To find out more about the release candidate, head over to <a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx">Scott Guthrie&#8217;s blog post</a>.</p>
<h3>Learning Resources</h3>
<p>A big advantage for anybody learning a new technology is the wealth of learning material that is available.  Although you can rely on a large number of books, the <a href="http://www.asp.net/learn">ASP.NET learn</a> website contains many videos on both traditional and MVC ASP.NET as well as data access.</p>
<h3>Intrinsic jQuery Support</h3>
<p>The lightweight open source JavaScript library that&#8217;s taken the web by storm is now fully supported by Microsoft.  As well as <a href="http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx">full intellisense support in Visual Studio</a>, Microsoft will be using the library as-is, without forking or changing the code from the main jQuery branch.  What&#8217;s more, Microsoft will be using jQuery as a basis for future ASP.NET and ASP.NET AJAX features.  I feel this counters the argument of Microsoft not supporting open-source software.</p>
<h3>Career Prospects</h3>
<p>Microsoft&#8217;s ubiquity means that learning ASP.NET and supporting technologies will do no harm to your career prospects.  <a href="http://www.cwjobs.co.uk/Content/PermanentDeveloperDemand.html">.NET skills are ranked as some of the most in-demand in the UK</a>.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2009/03/5-things-you-may-not-know-about-aspnet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programmatic impersonation in C#</title>
		<link>http://www.freshclickmedia.com/blog/2008/11/programmatic-impersonation-in-c/</link>
		<comments>http://www.freshclickmedia.com/blog/2008/11/programmatic-impersonation-in-c/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 20:08:47 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/?p=115</guid>
		<description><![CDATA[<img src="http://farm4.static.flickr.com/3054/3064284648_4a04bbfbed_o.jpg" alt="Impersonation" width="590" height="100" />

I recently deployed a WPF app on a server that allowed the user to stop and start some application-related services.  The purpose of the app was to allow users with administrative rights an easy way to manage the services that they needed to manage.  Granted, they could manage the services through the services MMC, but the little WPF app was a requirement, and it's our job as developers to make things easier for our clients - right?  

All went well until a change of requirements meant that a user without administrative rights needed to use the program to stop and start the required services.  When I tried to use the app, I got an exception - quite rightly, stopping and starting the services required admin rights.  We needed the restricted user to be able to log on and use the app, but still needed to restrict their permissions.

So - step in programmatic impersonation in C# - a way to give restricted users the power that that's required, all within the confines of your application.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm4.static.flickr.com/3054/3064284648_4a04bbfbed_o.jpg" alt="Impersonation" width="590" height="100" /></p>
<p>I recently deployed a WPF app on a server that allowed the user to stop and start some application-related services.  The purpose of the app was to allow users with administrative rights an easy way to manage the services that they needed to manage.  Granted, they could manage the services through the services MMC, but the little WPF app was a requirement, and it&#8217;s our job as developers to make things easier for our clients &#8211; right?  </p>
<p>All went well until a change of requirements meant that a user without administrative rights needed to use the program to stop and start the required services.  When I tried to use the app, I got an exception &#8211; quite rightly, stopping and starting the services required admin rights.  We needed the restricted user to be able to log on and use the app, but still needed to restrict their permissions.</p>
<p>So &#8211; step in programmatic impersonation in C# &#8211; a way to give restricted users the power that that&#8217;s required, all within the confines of your application.</p>
<p>The first thing to point out is that I got quite a bit of this code from a google search, but I had to do a bit of work to get things in a state that I found really useful.</p>
<pre class="code">using System;
using System.Collections.Generic;
using System.Configuration;
using System.Runtime.InteropServices;
using System.Linq;
using System.Security.Principal;
using System.Text;

namespace ServiceControllerApp.Security
{
    public class Impersonator : IDisposable
    {
        private WindowsImpersonationContext _impersonatedUser = null;
        private IntPtr _userHandle;

        public Impersonator()
        {
            _userHandle = new IntPtr(0);

            string user = &quot;servicecontroller&quot;;
            string userDomain = ConfigurationManager.AppSettings[&quot;MachineDomain&quot;];
            string password = &quot;yourpassword&quot;;

            bool returnValue = LogonUser(user, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);

            if (!returnValue)
                throw new ApplicationException(&quot;Could not impersonate user&quot;);

            WindowsIdentity newId = new WindowsIdentity(_userHandle);
            _impersonatedUser = newId.Impersonate();
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (_impersonatedUser != null)
            {
                _impersonatedUser.Undo();
                CloseHandle(_userHandle);
            }
        }

        #endregion

        #region Interop imports/constants
        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_LOGON_SERVICE = 3;
        public const int LOGON32_PROVIDER_DEFAULT = 0;

        [DllImport(&quot;advapi32.dll&quot;, CharSet = CharSet.Auto)]
        public static extern bool LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);
        #endregion
    }
}
</pre>
<p>Impersonator is a simple class that uses interop to call Win32 LogonUser and CloseHandle functions.  We have to use interop because .NET doesn&#8217;t provide the equivalent methods.</p>
<p>The code shown above has a user, domain and password actually in the code &#8211; for some situations this is a security risk, so the credentials should be obtained in another manner, but for my needs, it was satisfactory, and their direct inclusion simplifies this example.  </p>
<p>The class has a WindowsImpersonationContext to manage the impersonation, and the constructor sets up the required logon rights using the LogonUser interop.</p>
<p>Crucially, the impersonation must end, with an equivalent Log Off &#8211; and the class implements IDisposable to call the required log off code.  Using the class is easy.</p>
<pre class="code">
using (Impersonator impersonator = new Impersonator())
{
    // code in here
}
</pre>
<p>The good thing is that because the class implements IDisposable, you don&#8217;t have to pepper your code with the log off code equivalent.  I hope it&#8217;s of use to somebody wishing to implement impersonation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2008/11/programmatic-impersonation-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ASP.NET Gravatar Control Update &#8211; Full Source Included</title>
		<link>http://www.freshclickmedia.com/blog/2008/06/aspnet-gravatar-control-update-full-source-included/</link>
		<comments>http://www.freshclickmedia.com/blog/2008/06/aspnet-gravatar-control-update-full-source-included/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 20:45:32 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Blogging]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/?p=88</guid>
		<description><![CDATA[<img src="http://farm4.static.flickr.com/3047/2573024373_ba7d7eb151_o.jpg" alt="Gravatar ASP.NET Control" class="header" />

With <a href="http://www.gravatar.com">gravatar</a>s now becoming ubiquitous in blogs and forums, I have developed an ASP.NET Control that encapsulates their functionality in a simple, reusable component.  It's so easy to use, you can download and be using it on your ASP.NET sites within minutes.

I've since had a lot of interest in the source code for the control, and so this post describes how the control works, as well as providing a download containing the control, as well as the full control source and example website that uses the control.]]></description>
			<content:encoded><![CDATA[<p><img class="header" src="http://farm4.static.flickr.com/3047/2573024373_ba7d7eb151_o.jpg" alt="Gravatar ASP.NET Control" /></p>
<p>With <a href="http://www.gravatar.com">gravatar</a>s now becoming ubiquitous in blogs and forums, I have developed an ASP.NET Control that encapsulates their functionality in a simple, reusable component.  It&#8217;s so easy to use, you can download and be using it on your ASP.NET sites within minutes.</p>
<p>I <a href="http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/">introduced the control</a> in February of 2008, and <a href="http://www.freshclickmedia.com/blog/2008/03/gravatar-control-update/">updated the functionality</a> in March of 2008.</p>
<p>I&#8217;ve since had a lot of interest in the source code for the control, and so this post describes how the control works, as well as providing a download containing the control, as well as the full control source and example website that uses the control.</p>
<h3>OK, let me download it already!</h3>
<p><a href='http://www.freshclickmedia.com/wp-content/uploads/2008/06/gravatar.zip'>Download the Control</a> and get started.  Note that the demo projects included in the ZIP were written in Visual Studio 2005, so if you&#8217;re using Visual Studio 2008, you&#8217;ll need to convert the solution.  If you&#8217;ve not done a conversion before, just follow the instructions that Visual Studio provides.  Please also note that the solution will not open in Express Editions, since they do not support control projects.  However, you can still use the control that&#8217;s included in the ZIP file.</p>
<p>Unzip the .zip download, and you&#8217;ll have the following folder structure:</p>
<p><img src="http://farm4.static.flickr.com/3098/2573846412_eac00df65b_o.jpg" alt="Unzipped Folder structure" /></p>
<p>The root contains a small readme file, Visual Studio solution, FreshClickmedia.dll &#8211; the gravatar control assembly, Freshclickmedia.Web control project and GravatarSite website, which contains a few control examples.</p>
<p>Opening the solution in visual studio will give you this solution structure:</p>
<p><img src="http://farm4.static.flickr.com/3075/2573846554_66538578c4_o.jpg" alt="Gravatar Solution" /></p>
<p>Fire up the website, and you should see something like this:</p>
<p><img src="http://farm4.static.flickr.com/3255/2573846346_c648276ae6_o.jpg" alt="Gravatar Demo Website" /></p>
<h3>Examining the Code</h3>
<pre class="code">
    &lt;h1&gt;Gravatar Examples&lt;/h1&gt;

    &lt;h2&gt;My email address, size of 80 pixels:&lt;/h2&gt;
        &lt;fcm:Gravatar ID=&quot;Gravatar1&quot; runat=&quot;server&quot; Email=&quot;youremailaddress@domain.com&quot;
             OutputGravatarSiteLink=&quot;true&quot; Size=&quot;80&quot; /&gt;

    &lt;h2&gt;No email address, with default image (absolute url) specified:&lt;/h2&gt;
        &lt;fcm:Gravatar ID=&quot;Gravatar2&quot; runat=&quot;server&quot; Size=&quot;80&quot; DefaultImage=&quot;http://farm3.static.flickr.com/2375/2552064340_192825f989_o.jpg&quot; /&gt;

    &lt;h2&gt;Email address not associated with Gravatar, with no default image:&lt;/h2&gt;
        &lt;fcm:Gravatar ID=&quot;Gravatar3&quot; runat=&quot;server&quot; Email=&quot;thisemaildoesnotexist@freshclickmedia.com&quot; Size=&quot;80&quot;  /&gt;
</pre>
<p>The control requires an email address:</p>
<pre class="code">
&lt;fcm:Gravatar ID=&apos;Gravatar1&apos; runat=&apos;server&apos; Email=&apos;username@domain.com&apos; /&gt;
</pre>
<p>For my email address, I get the following generated HTML:</p>
<p><img src="http://farm3.static.flickr.com/2181/2283724305_24797cd8d5_o.gif" width="505" height="208" alt="Output for my email address" /></p>
<p>And if we look at the generated source:</p>
<pre class="code">
&lt;a id=&quot;Gravatar1&quot; href=&quot;http://www.gravatar.com&quot; title=&quot;Get your avatar&quot;&gt;&lt;img width=&quot;80&quot; height=&quot;80&quot; src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=ccf3b8c638f15d005e5d070aeb1a3923&amp;rating=G&amp;size=80&quot; alt=&quot;Gravatar&quot; /&gt;&lt;/a&gt;
</pre>
<p>The default produces a hyperlink off to the <a href="http://www.gravatar.com">Gravatar</a> site with a title &#8220;Get your avatar&#8221;.  The image contains the MD5 email hash, a rating of &#8220;G&#8221; (suitable for all audience types), and a size of 80.</p>
<h3>Customisation</h3>
<p>The control supports a number of properties supporting the customisation of its output.</p>
<h4>Size</h4>
<p>The size property of the control can be in the range 1 to 80.  If it is outside this range, a default of 80 will be used.</dd>
<h4>MaxAllowedRating</h4>
<p>The &#8216;highest&#8217; allowed rating of image.</p>
<ul>
<li>A G rated gravatar is suitable for display on all websites with any audience type.</li>
<li>PG rated gravatars contain may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence.</li>
<li>R rated gravatars may contain such things as harsh profanity, intense violence, nudity, or hard drug use.</li>
<li>X rated gravatars may contain hardcore sexual imagery or extremely disturbing violence.</li>
</ul>
<h4>OutputGravatarSiteLink</h4>
<p>True by default, determines whether a hyperlink linking to the gravatar website will be output around the image.</p>
<h4>LinkTitle</h4>
<p>&#8220;Get your avatar&#8221; by default, allows the customisation of the &#8216;title&#8217; attribute of the link (obviously doesn&#8217;t apply if OutputGravatarSiteLink property is set to false.)</p>
<h4>DefaultImage</h4>
<p>URL encoded URL, protocol included, of a GIF, JPEG, or PNG image that should be returned if either the requested email address has no associated gravatar, or that gravatar has a rating higher than is allowed by the &#8220;MaxAllowedRating&#8221; property.</p>
<p>The code snippet below shows the associated properties.</p>
<pre class="code">
&lt;fcm:Gravatar ID=&quot;Gravatar1&quot; runat=&quot;server&quot;
    Email=&quot;username@domain.com&quot;
    DefaultImage=&quot;http://www.site.com/default.jpg&quot;
    OutputGravatarSiteLink=&quot;true&quot; Size=&quot;40&quot; /&gt;
</pre>
<h3>Examining the control code</h3>
<p>The Gravatar control derives from <code>System.Web.UI.WebControls.WebControl</code> and overrides the <code>Render</code> method.</p>
<p>The various properties such as Email are all implemented as simple C# properties, with various attributes depending on the property.</p>
<pre class="code">
[Bindable(true), Category(&quot;Appearance&quot;), DefaultValue(&quot;80&quot;)]
public short Size
{
	get
	{
		return _size;
	}
	set
	{
		_size = value;
	}
}
</pre>
<p>These properties are then used in the <code>Render</code> method to write out HTML using the method&#8217;s <code>HtmlTextWriter</code> parameter.</p>
<p>The <code>Render</code> method begins by adding the default attributes to the render, ensuring that the size is within the valid range of 1 to 512, and initialises the gravatar URL:</p>
<pre class="code">
AddAttributesToRender(output);

// if the size property has been specified, ensure it is a short, and in the range
// 1..512:
try
{
    // if it's not in the allowed range, throw an exception:
    if (Size &lt; 1 || Size &gt; 512)
        throw new ArgumentOutOfRangeException();
}
catch
{
    Size = 80;
}

// default the image url:
string imageUrl = &quot;http://www.gravatar.com/avatar.php?&quot;;
</pre>
<p>If an Email address has been supplied, the <code>MD5CryptoServiceProvider</code> hashes the email and a <code>StringBuilder</code> converts this to the required format:</p>
<pre class="code">
if( !string.IsNullOrEmpty( Email))
{
    // build up image url, including MD5 hash for supplied email:
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

    UTF8Encoding encoder = new UTF8Encoding();
    MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();

    byte[] hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(Email));

    StringBuilder sb = new StringBuilder(hashedBytes.Length * 2);
    for (int i = 0; i &lt; hashedBytes.Length; i++)
    {
        sb.Append(hashedBytes[i].ToString(&quot;X2&quot;));
    }

    // output parameters:
    imageUrl += &quot;gravatar_id=&quot; + sb.ToString().ToLower();
    imageUrl += &quot;&amp;rating=&quot; + MaxAllowedRating.ToString();
    imageUrl += &quot;&amp;size=&quot; + Size.ToString();
}
</pre>
<p>The final part of the method assigns a default image, if one has been specified, outputs the site ink, if required, outputs the required attributes and tags.</p>
<pre class="code">
// output default parameter if specified
if (!string.IsNullOrEmpty(DefaultImage))
{
    imageUrl += &quot;&#038;default=&quot; + HttpUtility.UrlEncode(DefaultImage);
}

// if we need to output the site link:
if (OutputGravatarSiteLink)
{
    output.AddAttribute(HtmlTextWriterAttribute.Href, &quot;http://www.gravatar.com&quot;);
    output.AddAttribute(HtmlTextWriterAttribute.Title, LinkTitle);
    output.RenderBeginTag(HtmlTextWriterTag.A);
}

// output required attributes/img tag:
output.AddAttribute(HtmlTextWriterAttribute.Width, Size.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Height, Size.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl);
output.AddAttribute(HtmlTextWriterAttribute.Alt, &quot;Gravatar&quot;);
output.RenderBeginTag(&quot;img&quot;);
output.RenderEndTag();

// if we need to output the site link:
if (OutputGravatarSiteLink)
{
    output.RenderEndTag();
}
</pre>
<h3>Using the control on your own projects</h3>
<p>As previously mentioned, the download solution will not open properly in Express versions of Visual Studio, since it does not support control projects, but the control, included in the download is supported by all versions of Visual Studio, 2005 and later.</p>
<p>The easiest way to use the control is to add the control to the toolbox.  To do this, ensure that you are in design mode (looking at a web page), and right click on the &#8216;Standard&#8217; group header of the Toolbox.  From the context menu, select &#8220;Choose Items&#8221; and browse to the assembly (Freshclickmedia.Web.dll), and click “OK” to add.</p>
<p><img src="http://farm3.static.flickr.com/2064/2283724303_c96532e03b_o.gif" alt="Adding the control to the toolbox" width="505" height="361"  /></p>
<p>Once you&#8217;ve added the assembly, you should see the following:</p>
<p><img src="http://farm4.static.flickr.com/3170/2573127429_02824b40fd_o.jpg" alt="Gravatar Toolbox Item" /></p>
<p>From there, you can drag the control onto your page and start having fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2008/06/aspnet-gravatar-control-update-full-source-included/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>A quick tour of C# 3.0&#8217;s new language features</title>
		<link>http://www.freshclickmedia.com/blog/2007/12/a-quick-tour-of-c-30s-new-language-features/</link>
		<comments>http://www.freshclickmedia.com/blog/2007/12/a-quick-tour-of-c-30s-new-language-features/#comments</comments>
		<pubDate>Wed, 05 Dec 2007 13:37:41 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/blog/2007/12/a-quick-tour-of-c-30s-new-language-features/</guid>
		<description><![CDATA[With Visual Studio 2008 now fully released, I take a quick look at some of the new language features in C# 3.0.

I&#8217;ll start the overview with the introduction of two classes, Person, and MyExtensions.

    public partial class Person
    {
        public Person()
  [...]]]></description>
			<content:encoded><![CDATA[<p>With Visual Studio 2008 now <a href="http://weblogs.asp.net/scottgu/archive/2007/11/19/visual-studio-2008-and-net-3-5-released.aspx">fully released</a>, I take a quick look at some of the new language features in C# 3.0.</p>
<p><span id="more-73"></span><br />
I&#8217;ll start the overview with the introduction of two classes, Person, and MyExtensions.</p>
<pre class="code">
    public partial class Person
    {
        public Person()
        {
            LogCreation();
        }

        // automatic properties:
        public int Age { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public short NumberOfChildren { get; set; }

        // partial method:
        partial void LogCreation();
    }

    // this could (and probably would) be in a different file:
    public partial class Person
    {
        // partial method implementation:
        partial void LogCreation()
        {
            Console.WriteLine("Person created");
        }
    }
</pre>
<p>The Person class introduces two new language features.</p>
<h3>Partial Methods</h3>
<p>The LogCreation method in the Person class has been decorated with the &#8216;partial&#8217; keyword, meaning that it is a &#8216;partial method&#8217;.  </p>
<p>Partial methods add a lightweight event handling mechanism to C#.  They&#8217;re basically methods where the declaration or prototype is specified in the declaration of a partial class, but the implementation can only be provided in another declaration for that partial class.  In other words, a partial method will only compile if it is specified in one partial class definition and is the implementation is provided in another partial class definition, as shown above.</p>
<p>The &#8216;clever&#8217; thing is that because no definition for the method is provided, no IL code is produced for that method, so the resulting assembly is no bigger or slower than if the partial method wasn&#8217;t there in the first place.  This then begs the question &#8211; if an implementation isn&#8217;t provided, why have the prototype at all?  Well, you could set up some &#8216;hooks&#8217; into your code for specific methods, that may or may not be implemented by a developer.</p>
<p>The Person class invokes the partial method LogCreation, and because an implementation is provided, the code is executed.  If the second partial class definition didn&#8217;t exist, or the method wasn&#8217;t implemented, the code would not be executed.  In practice, they are used by some new LINQ (more on that shortly) SQL entity classes as a hook for property value change notification.  A partial method is called before a property value changes, and a partial method is called after the property value has changed.  If you wish to hook into these, you can implement the methods in your partial class and be notified.  If not, the partial methods are &#8216;removed&#8217; from the assembly&#8217;s output.  </p>
<p>Syntactically, there are a few rules for partial methods:</p>
<ol>
<li>Can only be defined and implemented in partial classes</li>
<li>Must specify the partial modifer</li>
<li>Must not specify an access modifier, but are private.  If an access modifier (even if it&#8217;s private) is specified, you&#8217;ll get a compiler error</li>
<li>They must return void</li>
</ol>
<p>A little less strict in some other areas:</p>
<ol>
<li>They can have arguments</li>
<li>The don&#8217;t have to be implemented</li>
<li>They can be static</li>
</ol>
<p>The second class, MyExtensions, is shown below:</p>
<pre class="code">
    public static class MyExtensions
    {
        // extension method
        public static bool IsEven(this int number)
        {
            return number % 2 == 0;
        }
    }
</pre>
<p>The MyExtensions class shown above may look familiar at first glance, but the this keyword in the method arguments makes it stand out as an extension method.</p>
<h3>Extension Methods</h3>
<p>Basically, extension methods are a way of &#8216;extending&#8217; a .NET type with a method so that it may be called on an instance of that method.</p>
<p>The example shown illustrates the rules that an extension method must be defined as static, in a static class, and contain the this keyword in the method arguments list.  The type of argument is the .NET type that is being extended.</p>
<p>The nice thing is that when you have an extension method, you can do something like this:</p>
<p><img src="http://farm3.static.flickr.com/2286/2088223227_ab2e224bb1_o.png" alt="Extension methods in the Visual Studio 2008 IDE" /></p>
<p>Our example extends int, and the Visual Studio 2008 IDE indicates our extension method with a little icon and associated text.  Perhaps I need to get out a little more, but I find extension methods quite exciting.</p>
<h3>Collection and Object initialization</h3>
<pre class="code">
// collection initializer:
List<Person> people = new List< Person>
{
    // object initializer:
    new Person { Age = 6, FirstName = "Andy", LastName = "Andrews", NumberOfChildren = 0 },
    new Person { Age = 46, FirstName = "Bob", LastName = "Bobbins", NumberOfChildren = 3 },
    new Person { Age = 19, FirstName = "Charlie", LastName = "Charles", NumberOfChildren = 0 }
};
</pre>
<p>Collection initialization is a shorter way of creating a collection and initialising it.  Whereas before, the list would have to be created, and each item added separately, the whole thing can be done in one swoop.</p>
<p>Object initialization is very similar, and makes it easier to create an object and set property values at the same time.</p>
<h3>Lambda Expressions</h3>
<p>For the three Person instances added to the list, you could specify an anonymous method in C# 2.0 to extract items (in our case items of type Person) from the list based on a set of &#8216;matching criteria&#8217;:</p>
<pre class="code">
List< Person> children = people.FindAll( delegate( Person p) { return p.Age < 18; } );
</pre>
<p>This is all well and good, but the problem with anonymous methods is that they're a little bit, well, clunky.  </p>
<p>With lambda expressions, we can rewrite the above 'query' as follows:</p>
<pre class="code">
    IEnumerable&lt;Person&gt; children =
                people.Select(p =&gt; p).Where(p =&gt; p.Age &lt; 18);
</pre>
<p>Basically, we're referring to an item in the list as 'p', selecting 'p', and filtering using the Where method where the Age of the item is less than 18.  At first, I found them a little strange syntactically, but I've got used to them now, and don't typically use the old style anonymous methods.</p>
<h3>LINQ, var and anonymous type projection</h3>
<p><a href="http://msdn2.microsoft.com/netframework/aa904594.aspx">LINQ</a> is part of C# 3.0 and it's going to revolutionise the way that .NET developers access and manipulate data.  The previous example showed how the Select and Where methods seem familiar to a SQL way of dealing with data.</p>
<p>I attended a <a href="http://www.developerday.co.uk/ddd/default.asp">DDD</a> event last year, and was introduced to the 'var' keyword during a presentation.  I'm guessing that it was new to my fellow developers present because there were several loud gasps from the attendees.  </p>
<p>Aaaggggh!  It's like the old days of variants!</p>
<pre class="code">
var myName = "Shane";
</pre>
<p>The thing to really shout about here is that it is not a variant!  The compiler simply infers the type from the data on the right side of the assignment, in this case, a string.  It is a string!  It is not a variant!</p>
<p>The reason that this keyword is introduced is for anonymous types, and the following example, with some new LINQ syntax thrown in for good measure, will illustrate:</p>
<pre class="code">
var adults =
    from p in people
    where p.Age &gt;= 18
    select new { Name = p.FirstName + " " + p.LastName, Age = p.Age }; // anonymous type projection
</pre>
<p>The first thing to note is that from, where and select keywords are exactly as in a SQL query, but that the from occurs first.  This is mandatory, and it's unusual position is because Visual Studio's intellisense can only offer member information based on the data that is being queried.  Because this is first, Visual Studio can offer help for the where clause and the select clause (which appears last.)  There are a <a href="http://msdn2.microsoft.com/netframework/aa904594.aspx">number of other methods and keywords</a>, but I'll keep things brief here.</p>
<p>You'll notice that we're referring to an item in the list as 'p', referencing 'p' in the where clause with the Age property of the Person class, and then doing a select.</p>
<p>This select is doing something more interesting than the earlier example (which was just selecting people from the list).  It is using anonymous type projection, whereby an anonymous type is created as a result of a select on the data.</p>
<p>The type doesn't have a name (therefore it's anonymous), and its properties can be specified 'on the fly'.  Here, we're creating a new type to merge the first name and last name as 'Name', and creating an 'Age' property for the Person 'Age' property.</p>
<p>Because this type is anonymous, we need to specify the var keyword, and let the compiler work things out by inferring the type.</p>
<pre class="code">
// local variable type inference:
foreach (var currentAdult in adults)
{
    Console.WriteLine(currentAdult.Name + ".  Their age is " +
          (currentAdult.Age.IsEven() ? "" : "not ") + "even");
}
</pre>
<p>Once again, type inference comes into play, and we loop through the selected adults.  Note that the previously demonstrated int extension method is used (IsEven).</p>
<p>Remember that the Person class had a LogCreation partial method that was implemented?  Well, that is called every time a Person is constructed, so for our collection, object initialization and output, we get the following:</p>
<p><img src="http://farm3.static.flickr.com/2398/2089056994_f4af8efd4b_o.png" alt="Program output with partial method implementation" /></p>
<p>If the partial method implementation is taken out of the Person class, everything still compiles, but we get the following:</p>
<p><img src="http://farm3.static.flickr.com/2086/2089056998_48705d82e0_o.png" alt="Program output with partial method implementation removed" /></p>
<p>So, that concludes my brief overview of new language features.  Without doubt, the var keyword is likely to cause some controversy, but it really isn't bad, and is in fact required for anonymous types (which I believe to be a very handy addition to the language.)</p>
<p>I'm certainly looking forward to using the new language features, and I hope you do too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2007/12/a-quick-tour-of-c-30s-new-language-features/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
