<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel xmlns:blog="http://www.dotnetnuke.com/blog/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
    <title>onDevelopment+=1;</title>
    <description>Posts about findings in my daily life as software developer.</description>
    <link>http://callicode.com/myBlogs/tabid/53/BlogId/1/Default.aspx</link>
    <language>en-US</language>
    <webMaster>jcallico@callicode.com</webMaster>
    <pubDate>Wed, 30 May 2012 02:19:09 GMT</pubDate>
    <lastBuildDate>Wed, 30 May 2012 02:19:09 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>Blog RSS Generator Version 4.0.0.0</generator>
    <item>
      <title>Avoiding DataTables for Table Valued Parameters by using IEnumerable&amp;lt;SqlDataRecord&amp;gt;.</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/59/Table-Valued-Parameters-without-DataTables.aspx</link>
      <description>&lt;p&gt;&lt;strong&gt;A little intro&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/bb510489.aspx"&gt;Table Valued Parameters&lt;/a&gt; were introduced in SQL Server 2008 as a solution to allow multiple rows of structured data to be passed as parameters to stored procedures. For a brief introduction to this subject please refer to this &lt;a href="http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters"&gt;article&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This feature immediately caught my attention but I’ve avoided it’s usage because I didn’t like the fact that on the examples I saw there was always the need to convert your in memory data structure to a &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx"&gt;DataTable&lt;/a&gt; which is in my opinion such a heavy class to instantiate just to pass a parameter, so I continued using &lt;a href="http://www.sql-server-helper.com/functions/comma-delimited-to-table.aspx"&gt;comma separated lists&lt;/a&gt; of identifiers or &lt;a href="http://msdn.microsoft.com/en-us/library/34e4kcbw.aspx"&gt;XML for more complex data&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;It wasn’t until recently that I had to integrate with existing stored procedures which already expected &lt;a href="http://msdn.microsoft.com/en-us/library/bb510489.aspx"&gt;Table Valued Parameters&lt;/a&gt; that I had to dig a little deeper on this subject.&lt;/p&gt;  &lt;p&gt;As it turns out the SqlClient supports populating &lt;a href="http://msdn.microsoft.com/en-us/library/bb510489.aspx"&gt;Table Valued Parameters&lt;/a&gt; not only from &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx"&gt;DataTable&lt;/a&gt; but also from &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.common.dbdatareader.aspx"&gt;DbDataReader&lt;/a&gt; or IEnumerable&lt;&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.server.sqldatarecord.aspx"&gt;SqlDataRecord&lt;/a&gt;&gt;. From these three options I prefer the latter since it’s relatively easy to extent one of the native collections to support IEnumerable&lt;&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.server.sqldatarecord.aspx"&gt;SqlDataRecord&lt;/a&gt;&gt; which can then latter be reused if needed and avoiding the need to using the more heavy &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx"&gt;DataTable&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A simple example using IEnumerable&lt;SqlDataRecord&gt; instead of DataTable.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Let’s say that we want to pass a collection of keys and values to a given stored procedure, so let’s start by defining the following SQL objects:&lt;/p&gt;  &lt;p&gt;- A User-Defined table representing a dictionary:&lt;/p&gt;  &lt;pre class="sql" name="code"&gt;CREATE TYPE dbo.DictionaryTable AS TABLE 
(
      [Key] VARCHAR(20),
      [Value] VARCHAR(20)
)&lt;/pre&gt;

&lt;p&gt;- A Stored Procedure expecting this table as parameter:&lt;/p&gt;

&lt;pre class="sql" name="code"&gt;CREATE PROCEDURE p_Sample_Stored_Procedure
(
      @Dictionary dbo.DictionaryTable READONLY
)
AS
 
      SET NOCOUNT ON
      
      SELECT * FROM @Dictionary
      
GO&lt;/pre&gt;

&lt;p&gt;So assuming that in our application we use a IDictionary&lt;string, string&gt; to store the data:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;var dictionary = new Dictionary&lt;string, string&gt;()
                {
                    {"Key 1", "Value 1"},
                    {"Key 2", "Value 2"}
                };&lt;/pre&gt;

&lt;p&gt;In our data access layer we can create a class which inherits from Dictionary&lt;string, string&gt; and implements IEnumerable&lt;SqlDataRecord&gt;.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;        public class DictionaryDataRecord : Dictionary&lt;string, string&gt;, IEnumerable&lt;SqlDataRecord&gt;
        {
            private string _keyColumnName = "Key";
            private string _valueColumnName = "Value";

            public DictionaryDataRecord()
            {
                
            }

            public DictionaryDataRecord(IEnumerable&lt;KeyValuePair&lt;string, string&gt;&gt; dictionary)
            {
                foreach (var item in dictionary)
                {
                    this.Add(item.Key, Convert.ToString(item.Value));
                }
            }

            public virtual string KeyColumnName
            {
                get { return this._keyColumnName; }
                set { this._keyColumnName = value; }
            }

            public virtual string ValueColumnName
            {
                get { return this._valueColumnName; }
                set { this._valueColumnName = value; }
            }

            #region Implementation of IEnumerable&lt;SqlDataRecord&gt;

            IEnumerator&lt;SqlDataRecord&gt; IEnumerable&lt;SqlDataRecord&gt;.GetEnumerator()
            {
                var record = new SqlDataRecord(
                    new SqlMetaData(this.KeyColumnName, SqlDbType.VarChar, 255),
                    new SqlMetaData(this.ValueColumnName, SqlDbType.VarChar, 255));

                foreach (var item in this)
                {
                    record.SetString(0, item.Key);
                    record.SetString(1, item.Value);

                    yield return record;
                }
            }

            #endregion
        }&lt;/pre&gt;

&lt;p&gt;Note how we need to specify the name of the columns of the target table which can be changed if needed. Also we have a constructor expecting a dictionary so it’s easier to create a new instance of this class using an existing dictionary as source.  &lt;br /&gt;

  &lt;br /&gt;In order to pass our in-memory dictionary as a parameter to the stored procedure we do this:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;	SqlParameter param = command.Parameters.AddWithValue("@Dictionary", new DictionaryDataRecord(dictionary));
	param.SqlDbType = SqlDbType.Structured;
	param.TypeName = "dbo.DictionaryTable";&lt;/pre&gt;

&lt;p&gt;Notice that we need to specify the type name of the User-Defined table in the same way we specify VARCHAR or DATETIME types.&lt;/p&gt;

&lt;p&gt;So this is how a simple program which executes the stored procedure and then writes the same data bounced back to console will look like:&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;using (var connection = new SqlConnection(connectionString))
{
	connection.Open();

	var command = new SqlCommand("p_Sample_Stored_Procedure", connection)
	{
		CommandType = CommandType.StoredProcedure,
	};

	SqlParameter param = command.Parameters.AddWithValue("@Dictionary", new DictionaryDataRecord(dictionary));
	param.SqlDbType = SqlDbType.Structured;
	param.TypeName = "dbo.DictionaryTable";

	using (var reader = command.ExecuteReader())
	{
		while (reader.Read())
		{
			Console.WriteLine(string.Format("Key: {0}, Value: {1}", reader["Key"], reader["value"]));
		}
	}
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;In the end&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given the options supported by the SqlClient I personally like this approach better. It may appear more complicated upfront but I think it’s worth it. I’ve always tried to avoid working with &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.dataset.aspx"&gt;DataSet&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx"&gt;DataTable&lt;/a&gt; instances unless there are no other options available and wanted to do the same here.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/myBlogs/tabid/53/EntryId/59/Table-Valued-Parameters-without-DataTables.aspx&gt;More ...&lt;/a&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/59/Table-Valued-Parameters-without-DataTables.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/59/Table-Valued-Parameters-without-DataTables.aspx</guid>
      <pubDate>Sun, 19 Feb 2012 16:15:54 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=59</trackback:ping>
    </item>
    <item>
      <title>Up with HTML5 but not running yet</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/58/Up-with-HTML5-but-not-running-yet.aspx</link>
      <description>&lt;p&gt;&lt;a href="http://oreilly.com/catalog/9780596806033"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="HTML5-Up-And-Running-Cover" border="0" alt="HTML5-Up-And-Running-Cover" align="right" src="/Portals/0/Blog/Files/1/58/Windows-Live-Writer-Up-with-HTML5-but-not-running-yet_13D63-HTML5-Up-And-Running-Cover_3.gif" width="184" height="240" /&gt;&lt;/a&gt;A couple of days ago I finished reading “&lt;a href="http://oreilly.com/catalog/9780596806033"&gt;HTML5: Up and Running&lt;/a&gt;” and I wanted to share my thoughts about this book.&lt;/p&gt;  &lt;p&gt;This is one of these books that you can read in one sitting, it’s very well written and full of examples.&lt;/p&gt;  &lt;p&gt;If you are a programmer, web designer or somehow familiar with the HTML markup language this book will help you discover the new features in HTML5 but not only that, it will also provide useful examples about how to detect HTML5 features in today’s browsers and will enable you to start taking advantage of these features while remaining compatible with other (should I say older) browsers which are far behind when it comes to HTML5 support.&lt;/p&gt;  &lt;p&gt;If, on the other hand, you are a technology enthusiast and have heard everybody using HTML5 as a buzzword this book will show you what the fuzz is all about.&lt;/p&gt;  &lt;p&gt;One of the things that became really clear to me after reading this book was that one of the most highlighted features in HTML5, &lt;a href="http://diveintohtml5.org/video.html"&gt;video support&lt;/a&gt;, is far from solved, and the battle between the different video containers and codecs for web supremacy is far from over. I was also not fully aware of all the licensing issues surrounding the popular H.264 (MPEG-4) video format.&lt;/p&gt;  &lt;p&gt;HTML5 features like &lt;a href="http://diveintohtml5.org/storage.html"&gt;Local Storage&lt;/a&gt;, &lt;a href="http://diveintohtml5.org/canvas.html"&gt;Canvas&lt;/a&gt; and Web Workers are going to forever change the way we write and use browser based application nowadays not to mention the fact that by using the new semantic HTML elements and &lt;a href="http://diveintohtml5.org/extensibility.html"&gt;microdata&lt;/a&gt; our documents are going to be better read and interpreted by other readers and applications allowing us to further act on the information contained on them.&lt;/p&gt;  &lt;p&gt;HTML5 is finally here, you better be prepared, but don’t expect that by the end of this book you will be an expert, this is just an introduction to the new world of possibilities that HTML5 is bringing to us.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/myBlogs/tabid/53/EntryId/58/Up-with-HTML5-but-not-running-yet.aspx&gt;More ...&lt;/a&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/58/Up-with-HTML5-but-not-running-yet.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/58/Up-with-HTML5-but-not-running-yet.aspx</guid>
      <pubDate>Sat, 09 Jul 2011 02:40:35 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=58</trackback:ping>
    </item>
    <item>
      <title>Maintaining indexes in MS-SQL</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/57/Maintaining-indexes-in-MS-SQL.aspx</link>
      <description>&lt;p&gt;More than half of the times I’m asked to troubleshoot performance issues on MS-SQL I end up finding a missing index as the cause of the problem. &lt;/p&gt;  &lt;p&gt;I’m sure that as part of the initial database design process the most important indexes are created, but  as the application evolves new queries are introduced and verifying if there is an index backing up the new query is usually an afterthought.&lt;/p&gt;  </description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/57/Maintaining-indexes-in-MS-SQL.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/57/Maintaining-indexes-in-MS-SQL.aspx</guid>
      <pubDate>Wed, 01 Jun 2011 18:23:14 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=57</trackback:ping>
    </item>
    <item>
      <title>How to create an instance of a generic type passing arguments to it&amp;rsquo;s constructor.</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/54/How-to-create-an-instance-of-a-generic-type-passing-arguments-to-it-rsquo-s-constructor.aspx</link>
      <description>&lt;p&gt;This is one of these things that I keep forgetting how to do and end up having to search my code library every time.&lt;/p&gt;  </description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/54/How-to-create-an-instance-of-a-generic-type-passing-arguments-to-it-rsquo-s-constructor.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/54/How-to-create-an-instance-of-a-generic-type-passing-arguments-to-it-rsquo-s-constructor.aspx</guid>
      <pubDate>Mon, 02 May 2011 19:25:42 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=54</trackback:ping>
    </item>
    <item>
      <title>Beware when mapping enumerations using NHibernate</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/53/Keep-it-simple-when-mapping-Enumerations-using-NHibernate.aspx</link>
      <description>&lt;p&gt;I’m almost positive that everybody who has used NHibernate beyond a simple Hello World application has been bitten by this. Today it was my turn.&lt;/p&gt;  </description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/53/Keep-it-simple-when-mapping-Enumerations-using-NHibernate.aspx#Comments</comments>
      <slash:comments>2</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/53/Keep-it-simple-when-mapping-Enumerations-using-NHibernate.aspx</guid>
      <pubDate>Thu, 21 Apr 2011 17:48:00 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=53</trackback:ping>
    </item>
    <item>
      <title>How to restore a SQL Server 7.0 database backup into SQL Server 2008</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/49/Restoring-a-MSSQL-2000-Database-Backup-into-2008.aspx</link>
      <description>&lt;p&gt;&lt;strong&gt;     &lt;br /&gt;The Problem&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I got the following error when trying to restore an old database backup into my local 2008 SQLEXPRESS instance:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://callicode.com/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-RestoreFailed_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Restore Failed" border="0" alt="The database was backed up on a server running version 7.00.1063. That version is incompatible with this server, which is running version 10.00.2531. Either restore the database on a server that supports the backup, or use a backup that is compatible with this server." src="/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-RestoreFailed_thumb.png" width="615" height="195" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;According to the SQL Server 2008 documentation:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The database being restored must be at least version 80 (SQL Server 2000) to restore to SQL Server 2008 R2. SQL Server 2000 or SQL Server 2005 databases that have a compatibility level less than 80 will be set to compatibility 80 when restored.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;The tedious workaround&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Luckily SQL Server 2005 is able to restore backups taken with version 7. A workaround is to install it as a new instance, restore the old backup file into an empty database, backup this database and restore it into SQL 2008.    &lt;br /&gt;    &lt;br /&gt;SQL Server 2005 Express can be downloaded from &lt;a href="http://www.microsoft.com/Sqlserver/2005/en/us/express-down.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The installation process is straightforward, only two steps are worth mentioning:&lt;/p&gt;  &lt;p&gt;1- When selecting the instance name and since SQLEXPRESS is already in use by SQL 2008 something else needs to be selected, I chose SQLEXPRESS2005 but anything else will also do the job.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://callicode.com/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_thumb_1.png" width="490" height="449" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2- If Windows Authentication was selected (default mode) then check the option to add your windows user to the SQL Administrator Role since this option is not checked by default. I missed it the first time and wasn’t able to do much since only had access to the “public” role. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://callicode.com/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_thumb_5.png" width="490" height="449" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;SQL Management Studio 2008 is able to connect to SQL 2005 instances so there is no need to install the Management Studio 2005.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://callicode.com/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_thumb_2.png" width="420" height="315" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now that we are able to connect to both instances…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://callicode.com/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/1/49/Windows-Live-Writer-Restoring-a_A895-image_thumb_3.png" width="401" height="118" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;… we simply restore the SQL 7.0 backup into SQL 2005, take a backup of the same database and restore it in 2008.&lt;/p&gt;  &lt;p&gt;After the database was restored into 2008 I uninstalled the SQL 2005 instance and was done.&lt;/p&gt;  &lt;p&gt;This solution worked but installing an extra instance of SQL just for restoring a database didn’t seem to me like the easier way.&lt;/p&gt;  &lt;p&gt;Again this is a very rare situation but I’ll update this article if I find an easier way.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/myBlogs/tabid/53/EntryId/49/Restoring-a-MSSQL-2000-Database-Backup-into-2008.aspx&gt;More ...&lt;/a&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/49/Restoring-a-MSSQL-2000-Database-Backup-into-2008.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/49/Restoring-a-MSSQL-2000-Database-Backup-into-2008.aspx</guid>
      <pubDate>Sat, 19 Feb 2011 17:01:55 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=49</trackback:ping>
    </item>
    <item>
      <title>Sometimes the best way to keep a client is to stop doing business with them</title>
      <link>http://callicode.com/Homeltpagegt/tabid/38/EntryId/48/Sometimes-the-best-way-to-keep-a-client-is-to-stop-doing-business-with-them.aspx</link>
      <description>&lt;p&gt;… at least for a while.   &lt;br /&gt;    &lt;br /&gt;This is the story of my relationship with a long-time client. I’ve been doing business with them for more than 10 years, but a few months ago I decided that by stopping our relationship I’d be doing them a favor - here is why:&lt;/p&gt;  &lt;p&gt;I started working for this company as a full time employee and because it was a small company, I had to do be proficient on a number of different levels, such as software development, network administration, support for existing applications, documentation specialist, meeting with clients, etc. It was a great learning experience for me, but eventually I wanted to concentrate on what really drives me – software development.&lt;/p&gt;  &lt;p&gt;So, after working there for 5 years, I decided to find another job. When I informed them of my decision, they asked me to continue maintaining a small server farm that hosted all their applications and services. I accepted, because I wanted to keep myself current with that subject, and more importantly, I considered it fair payback for the years that they had employed me.&lt;/p&gt;  &lt;p&gt;After a few months, I started to see the task of remote administration more as a hobby and less as a business. I tried to save this company as much money as I could, even under-billing for hours spent troubleshooting an issue. Due to this mindset, my support-style became reactionary – something I had promised never to do. In my opinion, this evolution occurred over time and resulted from my losing my objectivity and trying to be all things to this client – friend first, and solution provider, second.    &lt;br /&gt;The consequences are obsolete infrastructure, and a growing list of support tickets that needed to be resolved.&lt;/p&gt;  &lt;p&gt;In the end, I chose to terminate my relationship, because we had both grown beyond what the current situation described. I emailed and called them, detailing my reasons and though it was an initial shock, they understood, and I believe, appreciated my honesty.&lt;/p&gt;  &lt;p&gt;What have I learned from all this?&lt;/p&gt;  &lt;p&gt;1- Always keep yourself honest and be realistic about the quality of your work. If you don’t have the time, resources, or motivation to provide the best possible service to your clients, don’t keep them as clients.&lt;/p&gt;  &lt;p&gt;2- When you are ending a business relationship with a client, always try to make their transition process to the new service provider as smooth as possible – this benefits both the client, and you.&lt;/p&gt;  &lt;p&gt;3- Keep your focus on what you really want to do and remove distractions even if you will be impacted financially.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/Homeltpagegt/tabid/38/EntryId/48/Sometimes-the-best-way-to-keep-a-client-is-to-stop-doing-business-with-them.aspx&gt;More ...&lt;/a&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/Homeltpagegt/tabid/38/EntryId/48/Sometimes-the-best-way-to-keep-a-client-is-to-stop-doing-business-with-them.aspx#Comments</comments>
      <slash:comments>4</slash:comments>
      <guid isPermaLink="true">http://callicode.com/Homeltpagegt/tabid/38/EntryId/48/Sometimes-the-best-way-to-keep-a-client-is-to-stop-doing-business-with-them.aspx</guid>
      <pubDate>Tue, 18 Jan 2011 05:00:00 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=48</trackback:ping>
    </item>
    <item>
      <title>Extending WCF tracing to support trace file rotation</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/45/Extending-WCF-tracing-to-support-trace-file-rotation.aspx</link>
      <description>&lt;p&gt;The native support for &lt;a href="http://msdn.microsoft.com/en-us/library/ms733025.aspx"&gt;tracing in WCF&lt;/a&gt; is very good but as sometimes is the case is missing a functionality that I happen to need right now: The ability to rotate the trace files or in other words automatically switching to a new trace file based on a time based criteria.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Why do I need this?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’ve been working on a project that has come to rely heavily in the trace files as a way to keep track of all the calls made by partners. If something goes wrong the trace files are the place to go to find out what really happened. Tracing, which in my opinion should only be enabled to troubleshoot a given problem, is now always on and the trace file gets big, really big, so finding a given message comes with the price of downloading this trace file and then searching for a given text.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/ms732023.aspx"&gt;Service Trace Viewer Tool&lt;/a&gt; does a decent job opening these big trace files and even lets you define what segment of the trace file gets loaded based on a given time frame but still trying to restrict the size of the trace files has become a necessity.&lt;/p&gt;  &lt;p&gt;There is built in support for &lt;a href="http://msdn.microsoft.com/en-us/library/aa395205.aspx"&gt;Circular Tracing&lt;/a&gt; which basically switches between two files back and forth when a given size threshold is reached but this is not exactly what I need.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How I would like trace file rotation to be configured&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms733025.aspx"&gt;Configuring tracing&lt;/a&gt; is a very straight forward process which involves adding the following section to your configuration file.&lt;/p&gt;  &lt;pre class="xml" name="code"&gt;&lt;system.diagnostics&gt;
  &lt;sources&gt;
    &lt;source name="System.ServiceModel" propagateactivity="true"
            switchvalue="Information,ActivityTracing"&gt;
      &lt;listeners&gt;
        &lt;add name="xml" /&gt;
      &lt;/listeners&gt;
    &lt;/source&gt;
    &lt;source name="System.ServiceModel.MessageLogging"&gt;
      &lt;listeners&gt;
        &lt;add name="xml" /&gt;
      &lt;/listeners&gt;
    &lt;/source&gt;
  &lt;/sources&gt;
  &lt;sharedlisteners&gt;
    &lt;add name="xml" type="System.Diagnostics.XmlWriterTraceListener"
       initializedata="D:\applog\MyServiceTracingAndLogging-client.svclog" /&gt;
  &lt;/sharedlisteners&gt;
  &lt;trace autoflush="true" /&gt;
&lt;/system.diagnostics&gt;&lt;/pre&gt;

&lt;p&gt;Ideally I would like to use standard string formatting to timestamp the trace file. For example in order to get a daily trace file I would like to only have to add the following placeholders to the file name: &lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&lt;add name="xml" type="System.Diagnostics.XmlWriterTraceListener" 
initializedata="D:\applog\MyServiceTracingAndLogging-client-{0:yyyy}-{0:MM}-{0:dd}.svclog" /&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Extending XmlWriterTraceListener class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you pay attention to the configuration section above you will notice that the &lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.xmlwritertracelistener(VS.80).aspx"&gt;XmlWriterTraceListener&lt;/a&gt; class is used to generate the trace file. After taking a look at how this class is implemented I came with the simple idea of inheriting from this class, intercepting the calls to Flash(), Write() and WriteLine() and generating a new file name when it’s needed.&lt;/p&gt;

&lt;p&gt;Here is all the code you need. You can copy this class in the App_Code folder in your project.&lt;/p&gt;

&lt;pre class="c-sharp" name="code"&gt;namespace Callicode.System.Diagnostics
{
    using global::System;
    using global::System.Diagnostics;
    using global::System.IO;
    using global::System.Text;

    /// &lt;summary&gt;
    /// Extends the &lt;c&gt;System.Diagnostics.XmlWriterTraceListener&lt;/c&gt; class to include 
    /// datetime formating as part of the trace filename.
    /// Caution:
    /// Because &lt;c&gt;System.Diagnostics.XmlWriterTraceListener&lt;/c&gt; is not thread-safe, 
    /// the trace source may lock resources exclusively when outputting traces.
    /// &lt;/summary&gt;
    public class TimeStampedXmlWriterTraceListener : XmlWriterTraceListener
    {
        protected string originalFilename = string.Empty;
        protected string formatedFilename = string.Empty;

        public TimeStampedXmlWriterTraceListener(Stream stream)
            : base(stream)
        {
        }

        public TimeStampedXmlWriterTraceListener(Stream stream, string name)
            : base(stream, name)
        {
        }

        public TimeStampedXmlWriterTraceListener(TextWriter writer)
            : base(writer)
        {
        }

        public TimeStampedXmlWriterTraceListener(TextWriter writer, string name)
            : base(writer, name)
        {
        }

        public TimeStampedXmlWriterTraceListener(string filename)
            : base(GetFormatedFileName(filename))
        {
            originalFilename = filename;
            formatedFilename = GetFormatedFileName(filename);
        }

        public TimeStampedXmlWriterTraceListener(string filename, string name)
            : base(GetFormatedFileName(filename), name)
        {
            originalFilename = filename;
            formatedFilename = GetFormatedFileName(filename);
        }

        public override void Flush()
        {
            RecreateWriterIfObsolete();
            base.Flush();
        }

        public override void Write(string message)
        {
            RecreateWriterIfObsolete();
            base.Write(message);
        }

        public override void WriteLine(string message)
        {
            RecreateWriterIfObsolete();
            base.WriteLine(message);
        }

        protected virtual void RecreateWriterIfObsolete()
        {
            string newFormatedFileName;

            if (this.Writer == null || string.IsNullOrEmpty(originalFilename) || string.IsNullOrEmpty(formatedFilename) ||
                formatedFilename.Equals(
                    newFormatedFileName = GetFormatedFileName(originalFilename), StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }

            // closing existing writer
            this.Writer.Close();

            // creating a new writer using the new filename
            // this is pretty much what the base EnsureWriter method does but since it's internal can't be used here
            Encoding encodingWithFallback = GetEncodingWithFallback(new UTF8Encoding(false));
            string fullPath = Path.GetFullPath(newFormatedFileName);
            for (int i = 0; i &lt; 2; i++)
            {
                try
                {
                    this.Writer = new StreamWriter(fullPath, true, encodingWithFallback, 0x1000);
                    break;
                }
                catch (IOException)
                {
                    newFormatedFileName = Guid.NewGuid() + newFormatedFileName;
                    fullPath = Path.GetFullPath(newFormatedFileName);
                }
                catch (UnauthorizedAccessException)
                {
                    break;
                }
                catch (Exception)
                {
                    break;
                }
            }

            // updating field with new filename
            this.formatedFilename = newFormatedFileName;
        }

        protected static Encoding GetEncodingWithFallback(Encoding encoding)
        {
            // Exactly the base GetEncodingWithFallback was declared private.
            Encoding encoding2 = (Encoding)encoding.Clone();
            encoding2.EncoderFallback = EncoderFallback.ReplacementFallback;
            encoding2.DecoderFallback = DecoderFallback.ReplacementFallback;
            return encoding2;
        }

        protected static string GetFormatedFileName(string filename)
        {
            return string.Format(filename, DateTime.Now);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;In order to use the new class simply modify the line containing the reference to the &lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.xmlwritertracelistener(VS.80).aspx"&gt;XmlWriterTraceListener&lt;/a&gt; class.&lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&lt;add name="xml" type="Callicode.System.Diagnostics.TimeStampedXmlWriterTraceListener, App_Code" 
initializedata="D:\applog\MyServiceTracingAndLogging-client-{0:yyyy}-{0:MM}-{0:dd}.svclog" /&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Caveats &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;- The &lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.xmlwritertracelistener(VS.80).aspx"&gt;XmlWriterTraceListener&lt;/a&gt; class was not written with inheritance in mind and some key methods like EnsureWrite were declared private or internal making necessary to duplicate some code that could have been reused otherwise. 

  &lt;br /&gt;- Having to check for the filename every time Flush(), Write() or WriteLine() are invoked adds more latency to the process but it was the only safe way I found to make sure that the data was written to the right file.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/myBlogs/tabid/53/EntryId/45/Extending-WCF-tracing-to-support-trace-file-rotation.aspx&gt;More ...&lt;/a&gt;&lt;div class="tags"&gt;Tags: WCF&lt;/div&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/45/Extending-WCF-tracing-to-support-trace-file-rotation.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/45/Extending-WCF-tracing-to-support-trace-file-rotation.aspx</guid>
      <pubDate>Thu, 30 Dec 2010 05:00:00 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=45</trackback:ping>
      <blog:tag blog:url="http://callicode.com/myBlogs/tabid/53/TagID/5/Default.aspx">WCF</blog:tag>
    </item>
    <item>
      <title>Error 128 "ResGen.exe" exited with code -532459699.</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/44/Error-128-ResGen-exe-exited-with-code-532459699.aspx</link>
      <description>&lt;p&gt;This weekend I got the following error message when trying to build a VS 2010 solution     that I was able to build without any problems 2 days before:&lt;br /&gt;
&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;strong&gt;         &lt;br /&gt;
Error 128 "ResGen.exe" exited with code -532459699.&lt;br /&gt;
&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It was obvious to me that the problem was related to the resource files.&lt;/p&gt;
&lt;p&gt;After checking the properties for some of the resource files on my solution I noticed     that some of them didn't have a the "Custom Tool" property set.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Custom Tool not set" width="524" height="91" src="/Portals/0/BlogImages/ResGen.error.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Setting the value of "Custom Tool" to "GlobalResourceProxyGenerator" allowed     me to build my solution again.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Custom Tool value set to GlobalResourceProxyGenerator" width="525" height="117" src="/Portals/0/BlogImages/ResGen.error.fix.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;If you Google this error, the first link is a &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/589207/resgen-exe-problem"&gt;         Microsoft Connect&lt;/a&gt; entry created 5 days ago without any recommended workaround     yet.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/myBlogs/tabid/53/EntryId/44/Error-128-ResGen-exe-exited-with-code-532459699.aspx&gt;More ...&lt;/a&gt;&lt;div class="tags"&gt;Tags: VS2010&lt;/div&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/44/Error-128-ResGen-exe-exited-with-code-532459699.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/44/Error-128-ResGen-exe-exited-with-code-532459699.aspx</guid>
      <pubDate>Mon, 30 Aug 2010 05:00:00 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=44</trackback:ping>
      <blog:tag blog:url="http://callicode.com/myBlogs/tabid/53/TagID/13/Default.aspx">VS2010</blog:tag>
    </item>
    <item>
      <title>SEO and removing the www prefix from your site URL</title>
      <link>http://callicode.com/myBlogs/tabid/53/EntryId/41/SEO-and-removing-the-www-prefix-from-your-site-URL.aspx</link>
      <description>&lt;p&gt;I’ve been working on making &lt;a href="http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;callicode.com&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; more friendly to search engines. One of the first things to do when trying to improve you site’s ranking is to make sure that your content is only available from a unique URL otherwise it can be considered duplicate content and your site penalized (more details &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/www.impliedbydesign.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/articleshttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/three-search-engine-optimization-tips-for-urls-the-seo-firms-wont-tell-you.html"&gt;here&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; and &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/www.seobythesea.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/?p=212"&gt;here&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt;). Since most websites are configured to work with and without the www prefix you have to decide which one is going to be your site’s main domain and redirect all other requests accordingly preferable using a &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/en.wikipedia.orghttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/wikihttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/HTTP_301"&gt;301 redirection&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt;. &lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;I decided that &lt;a href="http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;callicode.com&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; was going to be the main domain and started looking for ways to get it done with minimal effort.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;First I tried to find a possible built in functionality on &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/www.dotnetnuke.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;DotNetNuke&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt;, which is the engine powering &lt;a href="http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;callicode.com&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt;. Up until version 05.04.04 this functionality is not supported. There are some commercial plug-ins specialised in SEO advertising such functionality but I did not wanted to follow that path since I was sure there was a free alternative out there.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;Next I downloaded and configured &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/urlrewriter.nethttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;UrlRewriter.Net&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt;. After trying for a while I gave up since couldn’t get the proper redirection to work.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;My next option was &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/urlrewriter.codeplex.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;Managed Fusion URL Rewriter&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; a URL manipulation engine based on the Apache mod_rewrite extension which works as a HTTP Module on your existing .NET site, was easy to configure and got the job done.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;Only the following steps are required:&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;1- &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/urlrewriter.codeplex.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/releaseshttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;Download&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; and unzip the file provided.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;2- Copy ManagedFusion.Rewriter.dll to your site’s bin folder.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;3- Modify your site’s web.config to include the following sections:&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;    &lt;configSections&gt;   &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;        &lt;section name="managedFusion.rewriter" type="ManagedFusion.Rewriter.Configuration.ManagedFusionRewriterSectionGroup"http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/configSections&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;  &lt;system.web&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;        &lt;httpModules&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;            &lt;add name="RewriterModule" type="ManagedFusion.Rewriter.RewriterModule, ManagedFusion.Rewriter"http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;        &lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/httpModules&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/system.web&gt;&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;  &lt;managedFusion.rewriter xmlns="&lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/managedfusion.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/xsdhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/managedFusionhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/rewriter""&gt;http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/managedfusion.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/xsdhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/managedFusionhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/rewriter"&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt;&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;rules engine="Apache" http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;    &lt;br http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&gt;  &lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/managedFusion.rewriter&gt;&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;p&gt;4- Create a file named “ManagedFusion.Rewriter.txt” on the root of your site with the following content:&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;  &lt;pre&gt;RewriteEngine On 
RewriteCond %{HTTP_HOST} ^www.callicode.com$ [NC] 
RewriteRule ^(.*)$ &lt;a href="http://callicode.com$1"&gt;http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp://callicode.com$1&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; [R=301,L]&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/pre&gt;

&lt;p&gt;And that’s it. You can verify that any request under &lt;a href="http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/www.callicode.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/"&gt;http:http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/www.callicode.comhttp:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/a&gt; is now redirected to the equivalent URL without the www prefix.&lt;http:http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/http:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/callicode.comhttp:http://callicode.com/http://callicode.com/callicode.comhttp://callicode.com/p&gt;&lt;br /&gt;&lt;a href=http://callicode.com/myBlogs/tabid/53/EntryId/41/SEO-and-removing-the-www-prefix-from-your-site-URL.aspx&gt;More ...&lt;/a&gt;</description>
      <author>jcallico@callicode.com</author>
      <comments>http://callicode.com/myBlogs/tabid/53/EntryId/41/SEO-and-removing-the-www-prefix-from-your-site-URL.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://callicode.com/myBlogs/tabid/53/EntryId/41/SEO-and-removing-the-www-prefix-from-your-site-URL.aspx</guid>
      <pubDate>Fri, 06 Aug 2010 05:00:00 GMT</pubDate>
      <trackback:ping>http://callicode.comDesktopModules/BlogTrackback.aspx?id=41</trackback:ping>
    </item>
  </channel>
</rss>
