in

code for eternity !!!

community website for .net freaks ;-)

Technology

  • T-SQL Function to Get Int From Varchar

    I recently had to write a T-SQL function which cleans up all non numeric characters from a varchar variable and returns the int value of the remaining numeric characters. If no numeric characters exist, the function should return zero. I thought it would be nice to share this with you and I hope you find this useful ;-) Here is the function:

        CREATE FUNCTION [dbo].[GetIntFromVarchar]
        (
            @originalString varchar(50)
        )

        RETURNS int

        AS

        BEGIN

            -- declare local variable to hold numeric characters
            -- and assign default value of empty string
            DECLARE @retVal varchar(50)
            SET @retVal = ''

            -- declare local variable to loop through @originalString
            -- and assign initial value of 1
            DECLARE @loop int
            SET @loop = 1

            -- loop through every character in @originalString
            WHILE @loop <= LEN(@originalString)

                BEGIN
                   
                    IF ISNUMERIC(SUBSTRING(@originalString, @loop, 1)) = 1

                        BEGIN
                           
                            -- if numeric character found, append it to @retVal
                            SET @retVal = @retVal + SUBSTRING(@originalString, @loop, 1)

                        END

                    SET @loop = @loop + 1 -- increment value of @loop by 1

                END
           
            -- set @retVal to '0' if no numeric characters found
            IF @retVal = ''

                BEGIN

                    SET @retVal = '0'

                END
           
            -- return int value of numeric characters found
            -- by casting @retVal to int
            RETURN CAST(@retVal as int)

        END

    Once you have created this function, execute below T-SQL statements to verify the same:

        PRINT dbo.GetIntFromVarchar('R1A2J3') -- returns 123
        PRINT dbo.GetIntFromVarchar('COOL456CODER') -- returns 456
        PRINT dbo.GetIntFromVarchar('789') -- returns 789
        PRINT dbo.GetIntFromVarchar('GEEK') -- returns 0

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 20 2008, 11:48 AM by raj with 1 comment(s)
    Filed under:
  • Developers are Born Brave

    Reality about software development. Below image says it all ;-) Cheers to every coder reading this blog post :-) Please scroll to the right if you cannot see the entire image at 1 glance or click here to view / download the image in a seperate window.

    Developers are Born Brave

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 16 2008, 05:15 PM by raj with 8 comment(s)
    Filed under: ,
  • Coders versus Project Managers

    Few months back, I got below joke emailed to me by my friend who is also a passionate coder. In my personal (and humble) opinion, below joke hits jackpot with the current state of 9 out of 10 IT companies in India, which are headed by people who have zero or very little technical background. And perhaps this explains why Indian IT companies still have to market themselves as low cost outsourcing destinations to win business any why we still dont have too many Product based IT companies in India :-) Is the story same in your country too? Let me know, I would love to hear :-)

    Here is the joke, enjoy and forward this to all your coder friends ;-)

    A woman in a hot air balloon realized she was lost.

    She reduced altitude and spotted a man below. She descended a bit more and shouted, "Excuse me, can you help me? I promised a friend I would meet him an hour ago but I don't know where I am."

    The man below replied, "You're in a hot air balloon hovering approximately 30 feet above the ground. You're between 40 and 41 degrees north latitude and between 59 and 60 degrees west longitude."

    "You must be an engineer" said the balloonist.

    "I am", replied the man. "How did you know?"

    "Well", answered the balloonist, "everything you told me is technically correct, but I've no idea what to make of your information, and the fact is I'm still lost. Frankly, you've not been much help at all. If anything you've delayed my trip even more."

    The man below responded, "You must be in management."

    "I am," replied the balloonist, "but how did you know?"

    "Well", said the man, "You don't know where you are or where you're going. You have risen to where you are due to a large quantity of hot air. You made a promise which you've no idea how to keep, and you expect people beneath you to solve your problems"

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 14 2008, 11:15 AM by raj with 4 comment(s)
    Filed under: ,
  • LINQ Single and SingleOrDefault

    We can use the Single extension method of LINQ to return the only element in a sequence that satisfies a specified condition. However the Single extension method would throw the System.InvalidOperationException when no element in a sequence satisfies a specified condition. In such a scenario, we can use the SingleOrDefault extenion method which would return the default value of a type instead of throwing the System.InvalidOperationException.

    Also, both Single as well as SingleOrDefault extension methods would throw the System.InvalidOperationException when more than one element in a sequence satisfy a specified condition. We can use First or Last extensions methods of LINQ in such scenarios.

    Code example (both in C# and VB.NET) with comments below:

    C#:

        // Create a new generic list of ints
        List<int> l = new List<int>();

        l.Add(1); // Add 1 to the list
        l.Add(5); // Add 5 to the list
        l.Add(3); // Add 3 to the list

        // Returns 1 as only 1 satisfies the condition
        int value = l.Single(i => i == 1);

        // Returns the default value of int which is 0
        // since no element in the list equals 4
        value = l.SingleOrDefault(i => i == 4);

        // Throws System.InvalidOperationException
        // since no element in the list equals 4
        value = l.Single(i => i == 4);

        // Throws System.InvalidOperationException
        // since both 5 and 3 are greater than 1
        value = l.Single(i => i > 1);
        value = l.SingleOrDefault(i => i > 1);

    VB.NET: 

        ' Create a new generic list of ints
        Dim l As New List(Of Integer)

        l.Add(1) ' Add 1 to the list
        l.Add(5) ' Add 5 to the list
        l.Add(3) ' Add 3 to the list

        ' Returns 1 as only 1 satisfies the condition
        Dim value As Integer = l.Single(Function(i) i = 1)

        ' Returns the default value of int which is 0
        ' since no element in the list equals 4
        value = l.SingleOrDefault(Function(i) i = 4)

        ' Throws System.InvalidOperationException
        ' since no element in the list equals 4 
        value = l.Single(Function(i) i = 4)

        ' Throws System.InvalidOperationException
        ' since both 5 and 3 are greater than 1
        value = l.Single(Function(i) i > 1)
        value = l.SingleOrDefault(Function(i) i > 1)

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 10 2008, 02:27 PM by raj with 2 comment(s)
    Filed under: ,
  • AddItem Extension Method for BulletedList, CheckBoxList, DropDownList, ListBox, RadioButtonList

    We would have to write the below code to add a new item (with value) to any of these 5 controls (BulletedList, CheckBoxList, DropDownList, ListBox, RadioButtonList)

    C#:

        bulletedList.Items.Add(new ListItem("text", "value"));
        checkBoxList.Items.Add(new ListItem("text", "value"));
        dropDownList.Items.Add(new ListItem("text", "value"));
        listBox.Items.Add(new ListItem("text", "value"));
        radioButtonList.Items.Add(new ListItem("text", "value"));

    VB:

        bulletedList.Items.Add(New ListItem("text", "value"))
        checkBoxList.Items.Add(New ListItem("text", "value"))
        dropDownList.Items.Add(New ListItem("text", "value"))
        listBox.Items.Add(New ListItem("text", "value"))
        radioButtonList.Items.Add(New ListItem("text", "value"))

    I find it quite painful to write so much code just to add a new item (with value) to these controls and so I created a new AddItem extension method for the ListControl class (since all these 5 controls inherit from the ListControl class)

    C#:

        public static void AddItem(this ListControl lc, string text, string value)
        {
            lc.Items.Add(new ListItem(text, value));
        }

    VB:

        <Extension()> _
        Public Sub AddItem(ByVal lc As ListControl, ByVal text As String, ByVal value As String)
            lc.Items.Add(New ListItem(text, value))
        End Sub

    Now I can simply write the above code in a much simpler and cleaner way like below:

    C#:

        bulletedList.AddItem("text", "value");
        checkBoxList.AddItem("text", "value");
        dropDownList.AddItem("text", "value");
        listBox.AddItem("text", "value");
        radioButtonList.AddItem("text", "value");

    VB:

        bulletedList.AddItem("text", "value")
        checkBoxList.AddItem("text", "value")
        dropDownList.AddItem("text", "value")
        listBox.AddItem("text", "value")
        radioButtonList.AddItem("text", "value")

    Just 1 extension method which works for 5 controls to solve the problem :-) Cheers to object inheritance and cheers to Extension Methods ;-)

    Note: You can find a list of other cool and useful Extension Methods coded by me here

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • Using Initial Capacity Constructor of StringBuilder for Extreme Performace

    You must have come across plenty of articles on the internet which talk about using the StringBuilder class when computing large strings for performance gains. Nothing wrong with that. However I have not seen many coders using the Initial Capacity constructor of the StringBuilder class which can further improve performace.

    Lets take a real world example. Suppose we had to compute a csv (comma seperated values) file for a table named Users which had the following structure:

    • UserID int
    • FirstName nvarchar(20)
    • LastName nvarchar(20)

    Our csv file would look like (for 2 records):

    1,Paul,Graham
    2,Scott,Guthrie

    Most coders would write the below code to compute the csv file:

        // Populate Users DataTable
        DataTable dtUsers = SomeFunctionWhichReturnsUsersDataTable();

        // Declare new StringBuilder
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        // Loop through Users DataTable
        for (int j = 0; j < dtUsers.Rows.Count; j++)
        {
            sb.Append(dtUsers.Rows[j]["UserID"].ToString()); // Append UserID
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["FirstName"].ToString()); // Append FirstName
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["LastName"].ToString()); // Append LastName
            sb.AppendLine(); // Append new line
        }

        return sb.ToString(); // Return StringBuilder contents

    Now lets write the above code more intelligently by using the Initial Capacity constructor of the StringBuilder class. We can actually guess the approximate length of the csv file before hand by considering below points:

    • Max length of UserID can be 10 characters, since max value of UserID can be 2147483647, since its datatype is int
    • Max length of FirstName can be 20 characters, since its datatype is nvarchar(20)
    • Max length of LastName can be 20 characters, since its datatype is nvarchar(20)
    • Also each csv file record has 2 comma characters which act as seperators, and 1 new line character

    Therefore the max length per record can be 54 characters (10[UserID] + 20[FirstName] + 20[LastName] + 2[2 comma characters] + 2[1 new line character]). So now we are absolutely sure that our csv file would have a max length of (54 * Number of Records) characters.

    If you are hell bent on having just one and only one memory allocation for the StringBuilder class, go ahead and set the Initial Capacity of the StringBuilder class to (54 * Number of Rows). However doing this would more often than not result in a lot of memory wastage as not all records would have their UserID set to 10 digit integers or their FirstName and LastName set to 20 character long strings. Therefore I usually follow the divide by 2 rule where I divide the max length per record value by 2. This way I am sure there wont ever be more than 2 memory (re)allocations and more often than not just a single memory allocation would do the job. Below is the intelligent version of above code:

        // Populate Users DataTable
        DataTable dtUsers = SomeFunctionWhichReturnsUsersDataTable();

        // Set a value of 54 to maxLengthPerRecord
        int maxLengthPerRecord = 54;

        // Apply divide by 2 rule
        maxLengthPerRecord = maxLengthPerRecord / 2;

        // Compute initialCapacity value
        int initialCapacity = dtUsers.Rows.Count * maxLengthPerRecord;
       
        // Declare new StringBuilder using the Initial Capacity constructor
        System.Text.StringBuilder sb = new System.Text.StringBuilder(initialCapacity);

        // Loop through Users DataTable
        for (int j = 0; j < dtUsers.Rows.Count; j++)
        {
            sb.Append(dtUsers.Rows[j]["UserID"].ToString()); // Append UserID
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["FirstName"].ToString()); // Append FirstName
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["LastName"].ToString()); // Append LastName
            sb.AppendLine(); // Append new line
        }
       
        return sb.ToString(); // Return StringBuilder contents
     

    You might be thinking this is too much of an effort to save on a few memory reallocations. But the geek in me tries to visualize the performance gains and number of memory reallocations (read garbage collection cycles which are so expensive) which can be saved if we had to do the same task for a table with many columns and tens of thousands of records :-)

    Note: You can also consider dividing the max length per record by 3 or even 4, it all depends on your data structures and data patterns. Also the above code example uses a DataTable. However you can apply the same logic on a generic list or a DataReader as well.

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • T-SQL Query to Find the Second Lowest Column Value in a Table

    After reading my earlier post T-SQL Query to Find the Second Highest Column Value in a Table a lot of users asked me to also help them with writing a query to find the second lowest column value in a table. So here it is: If we had a table named Employee which had a column named Salary and we had to find the second lowest Salary in the Employee table, the query for the same would be:

    SELECT TOP 1 Salary FROM (SELECT TOP 2 Salary FROM Employee ORDER BY Salary ASC) AS E ORDER BY Salary DESC

    If we ran the above query against the Employee table which had the following 5 rows:

    5000
    4000
    3000
    2000
    1000

    The subquery or the inner query would return the top 2 rows in ascending Salary order which would be:

    1000
    2000

    The outer query would then select the top 1 row from the subquery results in descending Salary order which would be:

    2000

    Note that if we had to get the fourth lowest Salary, we could do so by simply changing the subquery from TOP 2 to TOP 4

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted Apr 30 2008, 09:41 AM by raj with 2 comment(s)
    Filed under:
  • LINQ Last and LastOrDefault

    We can use the Last extension method of LINQ to return the last element in a sequence that satisfies a specified condition. However the Last extension method would throw the System.InvalidOperationException when no element in a sequence satisfies a specified condition. In such a scenario, we can use the LastOrDefault extenion method which would return the default value of a type instead of throwing the System.InvalidOperationException.

    Code example (both in C# and VB.NET) with comments below:

    C#:

        // Create a new generic list of ints
        List<int> l = new List<int>();

        l.Add(1); // Add 1 to the list
        l.Add(5); // Add 5 to the list
        l.Add(3); // Add 3 to the list

        // Returns 1 as only 1 satisfies the condition
        int value = l.Last(i => i == 1);

        // Returns 3 although both 5 and 3 are greater than 1
        // since 3 appears last in the list
        value = l.Last(i => i > 1);

        // Returns the default value of int which is 0
        // since no element in the list equals 4
        value = l.LastOrDefault(i => i == 4);

        // Throws System.InvalidOperationException
        // since no element in the list equals 4
        value = l.Last(i => i == 4);

    VB.NET:

        ' Create a new generic list of ints
        Dim l As New List(Of Integer)

        l.Add(1) ' Add 1 to the list
        l.Add(5) ' Add 5 to the list
        l.Add(3) ' Add 3 to the list

        ' Returns 1 as only 1 satisfies the condition
        Dim value As Integer = l.Last(Function(i) i = 1)

        ' Returns 3 although both 5 and 3 are greater than 1
        ' since 3 appears last in the list
        value = l.Last(Function(i) i > 1)

        ' Returns the default value of int which is 0
        ' since no element in the list equals 4
        value = l.LastOrDefault(Function(i) i = 4)

        ' Throws System.InvalidOperationException
        ' since no element in the list equals 4
        value = l.Last(Function(i) i = 4)

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted Apr 27 2008, 09:31 AM by raj with 2 comment(s)
    Filed under: ,
  • LINQ First and FirstOrDefault

    We can use the First extension method of LINQ to return the first element in a sequence that satisfies a specified condition. However the First extension method would throw the System.InvalidOperationException when no element in a sequence satisfies a specified condition. In such a scenario, we can use the FirstOrDefault extenion method which would return the default value of a type instead of throwing the System.InvalidOperationException.

    Code example (both in C# and VB.NET) with comments below:

    C#:

        // Create a new generic list of ints
        List<int> l = new List<int>();

        l.Add(1); // Add 1 to the list
        l.Add(5); // Add 5 to the list
        l.Add(3); // Add 3 to the list

        // Returns 1 as only 1 satisfies the condition
        int value = l.First(i => i == 1);

        // Returns 5 although both 5 and 3 are greater than 1
        // since 5 appears first in the list
        value = l.First(i => i > 1);

        // Returns the default value of int which is 0
        // since no element in the list equals 4
        value = l.FirstOrDefault(i => i == 4);
       
        // Throws System.InvalidOperationException
        // since no element in the list equals 4
        value = l.First(i => i == 4);

    VB.NET:

        ' Create a new generic list of ints
        Dim l As New List(Of Integer)

        l.Add(1) ' Add 1 to the list
        l.Add(5) ' Add 5 to the list
        l.Add(3) ' Add 3 to the list

        ' Returns 1 as only 1 satisfies the condition
        Dim value As Integer = l.First(Function(i) i = 1)

        ' Returns 5 although both 5 and 3 are greater than 1
        ' since 5 appears first in the list
        value = l.First(Function(i) i > 1)

        ' Returns the default value of int which is 0
        ' since no element in the list equals 4
        value = l.FirstOrDefault(Function(i) i = 4)

        ' Throws System.InvalidOperationException
        ' since no element in the list equals 4
        value = l.First(Function(i) i = 4)

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted Apr 25 2008, 06:22 PM by raj with 2 comment(s)
    Filed under: ,
  • Blackle - Energy Saving Search

    Google is the second brain for many coders hungry for information. I as a coder cannot imagine a single day at work without Google. Few days back (22 April to be precise), it was Earth's day and I was wondering how we as coders can do our bit for our planet and fight against Global Warming. So I thought I would blog about Blackle :-)

    The idea behind Blackle: Google uses white background which consumes more power, and considering the huge number of queries Google gets (about 200 million each day), according to calculations, a black version of Google would save 750 mega watts / hour per year.

    So next time you want to search for information, try http://www.blackle.com :-) For more info on Blackle, visit http://www.blackle.com/about

    Also help spread the word about Blackle by telling your coder friends about it, ask them to blog about Blackle incase they have a blog ;-)

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted Apr 24 2008, 08:45 PM by raj with 2 comment(s)
    Filed under:
  • Cool Extension Methods for IDataReader Interface

    I find it really annoying to use the GetOrdinal method of the DataReader class everytime I have to access data in a strongly typed manner using any of the Get[DataType] methods of the DataReader class. Have a look at below code:

        int employeeID = dr.GetInt32(dr.GetOrdinal("EmployeeID"));
        string firstName = dr.GetString(dr.GetOrdinal("FirstName"));
        bool enabled = dr.GetBoolean(dr.GetOrdinal("Enabled"));

    It would be so cool if I could directly specify the table column names like below:

        int employeeID = dr.GetInt32("EmployeeID");
        string firstName = dr.GetString("FirstName");
        bool enabled = dr.GetBoolean("Enabled");

    This would save me so much typing and make my code look so much cleaner. The power of Extension Methods make this possible :-) I created a new class named IDataReaderHelper which has 18 Extension Methods in all. You can simply pass the table column names instead of table column indexes to all these 18 Extension Methods, and these 18 Extension Methods would take care of the rest by calling the GetOrdinal method of the DataReader class internally :-). Have a look at the screen shot below:

    Note: For readability purpose, above screen shot just highlights 3 of the 18 Extension Methods present in the IDataReaderHelper class. The 18 Extension Methods present in the IDataReaderHelper class are:

    • GetBoolean
    • GetByte
    • GetBytes
    • GetChar
    • GetChars
    • GetData
    • GetDataTypeName
    • GetDateTime
    • GetDecimal
    • GetDouble
    • GetFieldType
    • GetFloat
    • GetGuid
    • GetInt16
    • GetInt32
    • GetInt64
    • GetString
    • GetValue

    You can find the entire source code for the IDataReaderHelper class as an attachment with this post available for download. To see all my posts on Extension Methods click here.

    Update: Guys please dont forget to check out the Chris's comments (2nd from top) regarding performance issues when using the GetOrdinal method of the DataReader class inside a loop. Thanks for your excellent feedback Chris :-)

    Update: Guys please dont forget to check out programatik's post here where he / she has compared performance (using GetOrdinal versus using int inside a loop). His / her post is in Portuguese so you can go to http://www.google.com/translate_t and translate programatik's post from Portuguese to English. It took me 30 minutes to figure out the language of this post ;-) Great work programatik ;-)

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • System.Data.DataSetExtensions Assembly Error in Visual Studio 2008 RTM

    After upgrading from Visual Studio 2008 Beta 2 to Visual Studio 2008 RTM, I got the following error when I tried to build my ASP.NET 3.5 project which was initially coded using Visual Studio 2008 Beta 2:

    Could not load file or assembly 'System.Data.DataSetExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

    This error occurs because with Visual Studio 2008 RTM, a newer version (3.5) of the System.Data.DataSetExtensions assembly is available and the older version (2.0) of the System.Data.DataSetExtensions assembly no longer exists.

    To resolve this error, simply change your web.config file from:

    <add assembly="System.Data.DataSetExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

    to:

    <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • Tip/Trick: Making Non Themeable Properties of ASP.NET Controls Themeable

    If you have been using ASP.NET themes feature in your ASP.NET projects, you surely must have come across situations where you wished you could set certain properties of controls via skins. For example, in all my ASP.NET projects, I always want to set the Display property of any validator control to Dynamic. Also, I simply hate the idea of setting the ValidationExpression property for every instance of the RegularExpressionValidator control I use in aspx / ascx files where I have to validate an email address. When I tried to set these two properties of the RegularExpressionValidator control via skin, I got the following errors:

    • The 'Display' property of a control type System.Web.UI.WebControls.RegularExpressionValidator cannot be applied through a control skin.
    • The 'ValidationExpression' property of a control type System.Web.UI.WebControls.RegularExpressionValidator cannot be applied through a control skin.

    This happens because the Display as well as the ValidationExpression properties of the RegularExpressionValidator control are not marked as Themeable. To overcome this, I found a really cool and simple solution (object inheritance to the rescue !!!). I created a new class called NewRegularExpressionValidator which inherits from the RegularExpressionValidator class, and provides a new implementation of these two properties by marking them as Themeable. I created this new class in a new class library project (named ClassLibrary1) and also added the System.Web reference to this class library project. Below is the code for the NewRegularExpressionValidator class:

    Next I added a reference to ClassLibrary1 project from my ASP.NET project and defined two skins (Default skin and Email skin) for the NewRegularExpressionValidator control. Have a look at the skin definitions below:

    Now I no longer have to explicitly set the Display and ValidationExpression property of each and every RegularExpressionValidator control which validates an email address. Instead, I can simply set their SkinID as Email ;-). See below screen shot on how to use the Email skin in aspx / ascx files:

    This also makes it super easy for me to change the ValidationExpression property for a particular type of validation if need be. For example, if a new business rule disallows all hotmail email addresses, I can simply change the ValidationExpression property in the Email skin instead of changing it in multiple aspx / ascx files where I am validating email addresses ;-)

    Also note that the Default skin makes sure that every instance of the NewRegularExpressionValidator control in my ASP.NET project (which does not specify a particular SkinID) will have its Display property automatically set to Dynamic ;-)

    Note: You can use the same above trick with many other controls to make their Non Themeable properties Themeable. One good example (which I have been using since years) is to make the MaxLength property of a TextBox control Themeable. I find it quite useful to set the MaxLength property of a TextBox through a skin for common inputs which are required in multiple pages of a website (like Email, Password, etc).

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • Cool TrimText Extension Method for TextBox

    Extension Methods are one of the most powerful features of .NET 3.5 and they can add a lot of flexibility to your code and help in cutting down your code size significantly if used wisely. I have been using a lot of Extension Methods in my code lately. One of them is the TrimText Extension Method for TextBox. While taking user input on any webform or winform (for example when users enter their First Name / Last Name), often, users accidentally add an extra space in the end. If you are a good coder, you would handle such common user mistakes by making sure to trim these input values before adding them to the database. Prior to .NET 3.5, we would have to write the below code to trim the TextBox text:

    C#:

    TextBox1.Text = TextBox1.Text.Trim();

    VB:

    TextBox1.Text = TextBox1.Text.Trim()

    Now lets see how Extension Methods can help cut down the size of our above code. We create a simple TrimText Extension Method in a static class (C#) or module (VB) like below:

    C#:

    public static class ExtensionMethods
    {

        public static void TrimText(this TextBox t)
        {
            t.Text = t.Text.Trim();
        }

    } 

    VB:

    Imports System.Runtime.CompilerServices

    Public Module ExtensionMethods

        <Extension()> _
        Public Sub TrimText(ByVal t As TextBox)
            t.Text = t.Text.Trim()
        End Sub

    End Module 

    Once we have our TrimText Extension Method in place, we can achieve the same task by simply calling the TrimText Extension Method from any TextBox object:

    C#:

    TextBox1.TrimText();

    VB:

    TextBox1.TrimText()

    Notice how we have cut down the code and the code looks so much neater now ;-) I will post a few more examples of useful Extension Methods which I am using over the coming weeks. For those new to .NET 3.5, click here to know more about Extension Methods.

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • Creating Self Signed SSL Certificates on IIS 6.0 and Windows Server 2003

    If you need to deploy and test your code in SSL environment on IIS 6.0 and Windows Server 2003, but you do not have a valid SSL certificate on your development / test server issued by a trusted third party Certificate Authority (since it costs money), you can easily do so by creating a self signed test certificate using a tool called SelfSSL which comes with IIS 6.0 Resource Kit Tools. SelfSSL is a console line application which is free to use :-). You can download IIS 6.0 Resource Kit Tools from here.

    After downloading and executing this kit, make sure you either choose Complete installation option or if you choose Custom installation option, make sure you have selected the SelfSSL feature. See below step by step screen shots for the Custom installation option.

    Step 1: Click Next.

    Step 2: Choose I Agree and click Next.

    Step 3: Enter appropriate details and click Next.

    Step 4: Choose Custom installation option if you just want to install SelfSSL else choose Complete installation option to install all features and click Next.

    Step 5: Enter the installation location and click Next.

    Step 6: Select SelfSSL and click Next.

    Step 7: Review settings and click Next.

    Step 8: Click Finish.

    Once you have successfully installed, click on Start > All Programs > IIS Resources > SelfSSL > SelfSSL to run the SelfSSL utility. On doing so, you should see the command prompt along with help instructions (see below screen shot).

    If you simply type selfssl.exe and press enter, it would use the default settings to install the SSL certificate which are equivalent to:

    /N:CN=<YOUR COMPUTER NAME> (common name of the certificate)
    /K:1024 (key length of the certificate)
    /V:7 (validity of the certificate in days)
    /S:1 (ID of the site to which the certificate needs to be installed)
    /P:443 (SSL port)

    Type selfssl.exe and press enter, then type y and press enter again to confirm the installation (see screen shot below).

    The most important option here is the site id parameter and SelfSSL uses the site id 1 by default which maps to "Default Web Site".

    To find the site id for any website in IIS 6.0 you can simply execute iisweb.vbs /query "<NAME OF THE WEBSITE>" from command prompt (see below screen shot).

    In the above screen shot, you can clearly see that I executed iisweb.vbs /query "Default Web Site" to find the site id for "Default Web Site" which is "W3SVC/1", however we are only interested in the text which follows "W3SVC/" which is "1".

    Suppose you had another website by the name "RajTest" and you wanted to install a test SSL certificate having common name "RajTestCertificate" valid for 10 days to "RajTest" on port 444, you would first find the site id for "RajTest" by executing the following command at command prompt: iisweb.vbs /query "RajTest". Once you know the site id for "RajTest" (lets assume it was "1234567") you would execute the following command at the SelfSSL command prompt: selfssl.exe /N:CN=RajTestCertificate /V:10 / S:1234567 /P:444

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

More Posts Next page »


StopGlobalWarming.org  
Powered by Community Server (Non-Commercial Edition), by Telligent Systems