# Tuesday, August 10, 2010
Tip of the Day: Creating a control that displays multiple types of messages using the IValidator interface
Tuesday, August 10, 2010 6:06:51 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 09, 2010
My first journey through expression trees and dynamic lambda expressions, and an explanation on how I got there. The end result is a case-insensitive search and a wildcard search function.
Monday, August 09, 2010 5:34:12 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, August 05, 2010
Tip of the Day: Extension method to HTML encode a string
Thursday, August 05, 2010 2:39:30 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 04, 2010
Tip of the Day: T-SQL Script to rename bulk columns
Wednesday, August 04, 2010 5:22:15 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 03, 2010
Retrieve the column name which have uniqie constraints on them in a CodeSmith template.
Tuesday, August 03, 2010 6:13:07 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 28, 2010
Recently, my shared hosting provider decided to "upgrade" their system, and in the process it pretty much decimated my web sites. I managed to get content back up, but nothing much works, and I just haven't had time to rectify that, starting with switching hosts. I have slowly started migrating things to the new host, and last night finally got around to upgrading das Blog and moving that site over. There were a few glitches, but my new host resolved them fairly quickly, and now I can start taking care of my backlog of posts I have earmarked for writing about.

It's been a busy few months, and the biggest achievement has been cashing at the WSOP this year. I almost did it twice even!

Now it's time to focus on the business and my technical skills again. The nice thing is that I finally got around to setting it up to allow me to blog from email, which makes it a LOT more convenient to post things, as I always have email handy. A lot has been going on, and some of the things I need to update:
  • Updating content from my main business site, Rubicon Computing Solutions, LLC (still need to migrate it so I can update the content)
  • Technical ScreeningsPossible technical interviewing skills seminar (working with a local recruiting firm to help put something together)
  • Tips of the Day
  • New tools and links which are cool (so need to get the Rubicon site working again to post these)


I am hoping this weekend I can make the time to get these moving again. So welcome to the updated blog!
Wednesday, July 28, 2010 7:58:20 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 11, 2010
Explore the INFORMATION_SCHEMA to get more useful metadata information on your database, much simpler than using sysobjects!
Thursday, March 11, 2010 4:02:00 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, March 10, 2010
Retaining employees after this economy changes needs to start now!
Wednesday, March 10, 2010 3:18:49 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, March 05, 2010
Script to ferret out those procs you forgot to create permissions for!
Friday, March 05, 2010 4:36:29 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 02, 2010
Tip of the Day: Manipulating ASP.Net validators client side
Tuesday, March 02, 2010 4:29:40 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, January 06, 2010
How to register class based user controls in a web project
Wednesday, January 06, 2010 3:52:06 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, December 30, 2009
Extension method for providing dynamic sorting based on field names of a List collection.
Wednesday, December 30, 2009 4:58:02 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, December 29, 2009
Two useful menu items to help eliminate "using" clutter in VS2008.
Tuesday, December 29, 2009 4:43:28 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, November 11, 2009
Adding carriage returns to SSIS package annotations
Wednesday, November 11, 2009 5:13:49 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, November 07, 2009
More promising features of VS2010
Saturday, November 07, 2009 3:45:19 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, November 06, 2009
Tip of the day: marking routines obsolete, and enforcing it!
Friday, November 06, 2009 3:43:11 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, October 31, 2009
Some of the great features of Visual Studio 2010 which are very appealing to me!
Saturday, October 31, 2009 4:22:38 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, October 30, 2009
Using generics to simplify getting data from a SqlDataRow or DataRow object.
Friday, October 30, 2009 4:17:54 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, October 29, 2009
Launch another program, and optionally wait for it to complete.
Thursday, October 29, 2009 4:12:31 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, October 28, 2009
A simple validation routine to validate a string meets the minimum and maximum length requirements.
Wednesday, October 28, 2009 4:09:54 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, October 14, 2009
WinForm: The base class % could not be loaded.
Wednesday, October 14, 2009 6:27:16 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, October 07, 2009
Interview screening and consulting
Wednesday, October 07, 2009 5:14:00 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, September 29, 2009
Using the MasterType directive to programatically access you Master Page.
Tuesday, September 29, 2009 5:34:35 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
Just a general rave about WebSpark, and a rant about PayPal.
Tuesday, September 29, 2009 5:23:27 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, September 25, 2009
Placing page trace information in a file instead of on the page
Friday, September 25, 2009 6:11:05 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, September 23, 2009
Interview question -- the virtual keyword
Wednesday, September 23, 2009 5:45:06 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
Fancy tooltips in WinForms!
Wednesday, September 23, 2009 4:58:23 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, September 22, 2009
Adding a WinForm tooltip without the control..
Tuesday, September 22, 2009 5:38:13 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
Why so few posts recently..
Tuesday, September 22, 2009 5:15:25 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, September 16, 2009
How to enumerate all the shortcut keys in the Visual Studio IDE
Wednesday, September 16, 2009 6:22:12 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I am getting settled in my new project, and it only took me a week to get rights to install anything on the laptop! A lot of people would say "Wow, a billable week with no work!" but personally, the days just drag by. I'd much rather be buried in code. I did make some good use of the time though, digging into what documentation I could find and creating a new Functional Specification Document. I did finally get my rights, so tomorrow will be spent installing things and looking into code again.

I did get some reading done though, and I saw that in VS2010 C# will have optional and named parameters. I know the VB crowd (of which I come from) will chuckle a little at that, as that feature has been around forever. Until now, it's required C# developers to overload functions. Nothing Earth-shattering about this feature, other than as part of it, C# will support named parameters and default values as well as part of the implementation (the default values are part of the defiinition of the function).

All Things | C# | CSharp | General | VB.Net
Wednesday, September 16, 2009 5:36:56 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, September 07, 2009
Debugging trick for placing a condition on a breakpoint to assist in speeding up debugging.
Monday, September 07, 2009 11:46:14 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
How to make the Visual Studio debugger break where the error actually occurs.
Monday, September 07, 2009 11:28:20 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, September 05, 2009

As I was looking through Scott Hanselman's List of Tools for 2009, I saw a reference for Microsoft's Sketchflow (part of Microsoft Expression), which allows you to design (among other things) and work through ideas prior to coding. I am going to check it out this weekend, and maybe some of the alternate tools he recommended for his post.  I might even have to dust off my Table PC, as it seems like a good combination.

Saturday, September 05, 2009 4:55:17 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, September 04, 2009
Tipf of the Day: A brief discussion of the new Extension Methods in .Net 3.5
Friday, September 04, 2009 6:10:29 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, September 03, 2009
Starting a new project, how to approach it?
Thursday, September 03, 2009 8:41:58 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, September 02, 2009

I can't take credit for this, as I took it from the article How To Get Table Row Counts Quickly And Painlessly on SqlServerCentral.com by Kendal Van Dyke. However, it such a good tip, I had to change it a bit, as I tend to use this a LOT.

First, I made the results a little more "printable" but reducing the table name column. Next, I made it a system proc because when I go onto client sites, I am looking at many databases. I probably don't need to create a procedure for it, but there have been many cases where I trend things, and it would be nice to have this handy. Finally, I added a parameter to allow me to change the sorting. By default, it sorts by table name. I added an optional parameter to allow me to pass in an integer (could have done it a million ways, I know, but I chose to do this solely for my preferences -- feel free to change to yours).

Usagesp_retrieveRowCounts    --- sorts by table name

            sp_retrieveRowCounts 1  ---sorts by row count, then table name

Here's the proc:


USE master
GO

IF (SELECT OBJECT_ID('sp_retrieveRowCounts','P')) IS NOT NULL
BEGIN
    DROP PROC sp_retrieveRowCounts
END
GO


CREATE PROC sp_retrieveRowCounts (@OrderByCount int = null)
AS
BEGIN

    DECLARE @OrderByParm int
    DECLARE @SQLStatement varchar(700)
    DECLARE @OrderByClause varchar(35)
    
    SELECT @OrderByParm = ISNULL(@OrderByCount,0)

    IF (@OrderByParm != 0)
        SELECT @OrderByClause = ' ddps.row_count DESC, o.NAME ASC'
    ELSE
        SELECT @OrderByClause = ' o.NAME ASC'

    SELECT @SQLStatement = 'SELECT TableName = LEFT(o.name,50), TotalRows = ddps.row_count FROM sys.indexes AS i
     INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID
     INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID
     AND i.index_id = ddps.index_id
    WHERE i.index_id < 2
     AND o.is_ms_shipped = 0
    ORDER BY '
+ @OrderByClause
    
    EXEC(@SQLStatement)

END

--Mark procedure as system object
EXEC sys.sp_MS_marksystemobject sp_retrieveRowCounts
GO


GRANT EXEC ON sp_retrieveRowCounts TO public
GO

 

Wednesday, September 02, 2009 6:34:10 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, September 01, 2009

I posted about sp_findsp previously and decided to revisit it. I didn't write it (see previous post for credit/link) but I did add a bit to it. First, I cleaned it up a bit to make it easier to read, and second, I made it so that it is a system proc so I could access it from any db on my server. I may end up doing some cleanup on it's output, but that's all I had time for for now. So here goes, the new version!

USE master
GO

PRINT 'Checking for the existence of this procedure'
IF (SELECT OBJECT_ID('sp_generate_inserts','P')) IS NOT NULL --means, the procedure already exists
BEGIN
PRINT 'Procedure already exists. So, dropping it'
DROP PROC sp_findsp
END
GO


CREATE PROC sp_findsp @s varchar(255)
AS
BEGIN
    DECLARE @msg varchar(255) ,@ul varchar(255)
    SELECT @s='%' + @s + '%'
    
    SELECT 'SP Name'=upper(o.name), Seq=colid ,'SP Line'=substring(text,patindex(@s,text)-5, 30)
    FROM syscomments c , sysobjects o
    WHERE o.id=c.id
    and patindex(@s,text) > 0
    ORDER BY [name]

    SELECT @msg='* Stored procedures containing string "' + @s + '=' + convert(varchar(8),@@rowcount) + ' *'

    SELECT @ul=replicate('*',datalength(@msg))
    PRINT ' '
    PRINT @ul
    PRINT @msg
    PRINT @ul
END
GO

--Mark procedure as system object
EXEC sys.sp_MS_marksystemobject sp_findsp
GO

PRINT 'Granting EXECUTE permission on sp_findsp to all users'
GRANT EXEC ON sp_findsp TO public

GO


All Things | C# | CSharp | General
Tuesday, September 01, 2009 5:20:43 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 

When I go onto a client site, I usually don't have the luxury of designing everything from scratch. There are times (like on my current engagement) if I were given the choice, I'd say scrap it, but usually it doesn't happen that way. It is what it is... been saying that a lot lately!

So one of the tools I find useful is the ability to search for particular field names in the database. This is very similar to sp_findsp I use, which I have posted in the past off the net, but I have modified it so it gets registered as a system procedure.

So here's sp_findfields. It will return a fairly printable representation of the results of all fields which match the passed in string. It's registered as a system procedure in this script, so it is accessible to all databases.

Usage:

sp_findfields '%Contact%'

This will find all fields with the string 'Item' in it. Note you need to provide the wildcard characters.

USE master
GO

IF (SELECT OBJECT_ID('sp_findfields','P')) IS NOT NULL
    BEGIN
        DROP PROCEDURE sp_findfields
    END
GO

CREATE PROCEDURE sp_findfields
(@searchText varchar(50))
AS
BEGIN
    
    SELECT SchemaName = LEFT(TABLE_SCHEMA,10),
        TableName = LEFT(TABLE_NAME, 35),
        FieldName = LEFT(COLUMN_NAME, 40),
        DataType = LEFT(DATA_TYPE, 13),
        DataSize = CHARACTER_MAXIMUM_LENGTH,
        AlloysNulls = IS_NULLABLE
    FROM INFORMATION_SCHEMA.columns
    WHERE column_name like @searchText
    ORDER BY TableName, FieldName
END
GO

--Mark procedure as system object
EXEC sys.sp_MS_marksystemobject sp_findfields
GO


GRANT EXEC ON sp_findfields TO public
GO

Tuesday, September 01, 2009 5:10:15 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 31, 2009

Since I am going back into full time consulting, I decided lugging around twenty 800 page books is a bad idea. Tonight, I pulled the trigger in a Kindle DX. A bit pricy, but the fact I can annotate my books (and export the annotations) and read native PDFs, I can see the value in the price. I only wish it allowed you to annotate PDFs, as I know I can put a LOT of things in PDF form and place on there.

So I was noticing Amazon charges for placing RSS feeds on the Kindle, and I decided to either find a service which converts RSS feeds to PDF format, or write one myself. Fortunately, I found Tabbloid, which mails your RSS feeds in PDF format at an interval you specify. Even better, it looks free. I may still write one and put some filtering capability in it, but this is a win for now.

The other gadget I have and just enjoy is my Pioneer XMp3 player. It allows me to record XM content, and place all kinds of music on the Micro SD card. It's still kind of buggy, and with the XM-Sirius merger, I don't imagine that will change, but I still enjoy it immensely.

Monday, August 31, 2009 5:26:21 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, August 30, 2009

Normally, I don't have enough time to really dig into the bleeding edge technologies, but I am trying to rectify that. The question is always "When is it too early.."

For now, I have been looking at some of .Net 4.0's newer features, and one really cool thing for environments which have years of legacy software is called "Multi-targeting". Essentially, it allows you set the target environment for an application in the same IDE (but later target new versions).

As an example, let's say you are currently using ASP.Net 2.0, and you have to because of client concerns. No problem, you'll be able to set the VS IDE to target the 2.0 framework. However, when you decide to upgrade, you can just change the target framework version. The neat thing is that the IDE willl hide and show Intellisense based on the target framework as well.

Scott Guthie is writing a series on it I plan on following closely. This time, I may just have to be more bleeding edge than I have been in the past.

Sunday, August 30, 2009 4:31:31 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, August 29, 2009

The following code snippets make retrieving values from DataRows safely, and properly casts them to the desired values.

 

        /// <summary>

        /// Gets the int value from data row.

        /// </summary>

        /// <param name="fieldName">Name of the field.</param>

        /// <param name="dr">The dr.</param>

        /// <returns></returns>

        public static int GetIntValueFromDataRow(string fieldName, DataRow dr)

        {

            return (dr[fieldName] == DBNull.Value ? 0 : Convert.ToInt32(dr[fieldName].ToString()));

        }

 

        /// <summary>

        /// Gets the int value from data row.

        /// </summary>

        /// <param name="fieldName">Name of the field.</param>

        /// <param name="dr">The dr.</param>

        /// <param name="defaultValue">The default value.</param>

        /// <returns></returns>

        public static int GetIntValueFromDataRow(string fieldName, DataRow dr, int defaultValue)

        {

            return (dr[fieldName] == DBNull.Value ? defaultValue : Convert.ToInt32(dr[fieldName].ToString()));

        }

 

        /// <summary>

        /// Gets the string value from data row.

        /// </summary>

        /// <param name="fieldName">Name of the field.</param>

        /// <param name="dr">The dr.</param>

        /// <returns></returns>

        public static string GetStringValueFromDataRow(string fieldName, DataRow dr)

        {

            return (dr[fieldName] == DBNull.Value ? String.Empty : dr[fieldName].ToString());

        }

 

        /// <summary>

        /// Gets the string value from data row.

        /// </summary>

        /// <param name="fieldName">Name of the field.</param>

        /// <param name="dr">The dr.</param>

        /// <param name="defaultValue">The default value.</param>

        /// <returns></returns>

        public static string GetStringValueFromDataRow(string fieldName, DataRow dr, string defaultValue)

        {

            return (dr[fieldName] == DBNull.Value ? defaultValue : dr[fieldName].ToString());

        }

 

        /// <summary>

        /// Gets the bool value from data row.

        /// </summary>

        /// <param name="fieldName">Name of the field.</param>

        /// <param name="dr">The dr.</param>

        /// <returns></returns>

        public static bool GetBoolValueFromDataRow(string fieldName, DataRow dr)

        {

            return (dr[fieldName] == DBNull.Value ? false : Convert.ToBoolean(dr[fieldName].ToString()));

        }

 

        /// <summary>

        /// Gets the decimal value from data row.

        /// </summary>

        /// <param name="fieldName">Name of the field.</param>

        /// <param name="dr">The dr.</param>

        /// <returns></returns>

        public static decimal GetDecimalValueFromDataRow(string fieldName, DataRow dr)

        {

            return (dr[fieldName] == DBNull.Value ? 0 : Convert.ToDecimal(dr[fieldName].ToString()));

        }

Saturday, August 29, 2009 7:32:59 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, August 28, 2009

I am a huge fan of CodeSmith. If you are not familiar with it, and you do any amount of coding at all, you owe it to yourself to check it out.

Below is some template code which loads the foreign keys of a table into a Dictionary object. It stores the name of the table and foreign key field name. As you can see, it generates a notice when it comes across a recursive relationship.

 

public Dictionary<string,string> GetForeignKeyTables()
{
    Dictionary<string,string> dic = new Dictionary<string,string>( );

 for (int idx = 0; idx < SourceTable.ForeignKeys.Count; idx ++)
 {
        string primaryTable = String.Empty;
        string primaryKey = String.Empty;

  // To get the foreign key columns
  ColumnSchema col1 = SourceTable.ForeignKeys[idx].ForeignKeyMemberColumns[0];
        primaryKey = col1.Name.Trim();

  // To get the foreign key tables
        primaryTable = SourceTable.ForeignKeys[idx].PrimaryKeyTable.ToString().Replace("dbo.",String.Empty).Trim();
        if (!dic.ContainsKey(primaryKey))
            dic.Add(primaryKey, primaryTable);
        else
            MessageBox.Show("This table may contain recursive relationships. You must set those relationships up manually.");
    }

    return dic;
}

 

Friday, August 28, 2009 10:48:39 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, August 27, 2009
Interview question -- non-technical about how I handle release problems.
Thursday, August 27, 2009 12:01:11 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 25, 2009
An example of reflection in coding!
Tuesday, August 25, 2009 6:12:16 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Today has been an insanely busy day, but I have so much I want to blog about, and this one won't wait. A few days ago, as I was using some code I found on the net, I commented here about the over-use of the var keyword.

Seems I am not the only one who has an opinion on the matter. I subscribe to the CodeProject newsletter, and each issue features a survey. This week, the survey relates to the opinion of the var type in C#. You can see the survey results here. Make sure you click through to the "optional text answers" for some funny comments (and a few relevant ones as well).

The interesting thing to note from the survey is that the answers tend to skew towards the "never use that scenario" range. The two areas where it is most prevalent is with LINQ, and with anonymous types, which makes total sense.

All Things | C# | CSharp | Design | General
Tuesday, August 25, 2009 5:28:04 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 24, 2009

Question: What's reflection, and how have you used it to solve a problem?

Answer: Reflection is a way to look at assembly metadata and look in and see what is contained. It also allows you to use late binding and call methods within those assembles.

For the second part, a simple explanation is all you need to show that you understand how it is used.

So what if you've enver used reflection? First, shame on you (kidding!). It DOES serve a very important purpose and allows for some great solutions, especially at an architectural level. If you've never used it, I recommend immediately trying it out, and you'll find many, many uses. Here's a tutorial I found that looks decent. That way, when asked this question (and I get this one a lot) you can answer how you *might* really use it. Honestly, you've probably used it and didn't realize it if you've added certain attributes to your code.

I have used reflection for everything from identifying certain classes and functions. For example, for a coding sample, I used LINQ for Reflection and attributes to identify classes which supported certain calculations. By doing this, I could add more functions dynamically and the UI would pick it without changing code. Since LINQ for Reflection is not discussed much, I'll post some about that later.

There are some costs associated with Reflection though. Speed! Late Binding is slower by it's nature, as well as all the processing looking for methods, so plan and use wisely!

Monday, August 24, 2009 3:27:02 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, August 23, 2009

As a full time developer, I search the web... a lot. If you are writing a lot of new code without at least searching to see what exists, you're either getting paid by the hour (or line of code), stubborn or a glutton for punishment. Even if I don't use it, I can get some guidance on what someone else tried, and how it worked out before I start coding. Granted, it usually requires a lot of refactoring the code to my standards or needs, but it's a great start.

As I was thinking of things I wanted to put on my site, I realized it would be nice to share my "favorites"...sort of. If I found something useful, I wanted to be able to show what it was, how I found it useful and where someone else can find it. In a way, I am also helping to promote someone else's hard work and improving their search engine visibility to return the favor of their sharing their work.

Out of this, I came up with an idea for a "Useful Links" section. I wanted to be able to add links and commentary, and also add it to my Activity Aggregator to show help show the content of the site has changed. Later, as I was using Bing, I got the idea to add some webthumbs to enhance the page graphically, so the reader would know what the site looked like before going there. I also needed to add an admin page for creating the useful links (and ultimately maintaining them -- which is on my TODO list). I'll also leave out the icon creation part, although I really need to farm out for a new cool looking icon, which is also on my list of things to do.

I'll skip the admin section, as it's just data entry fields. The process for creating the entries does change a bit, as I needed to do a few extra steps.

  1. Save the UsefulLink class
  2. Default the webthumb image to a default "safety" image in case we can't get a webthumb
  3. Make a request to get a webthumb image of the target site
  4. Once the image is retrieved, update the UsefulLink record to point to the new webthumb
  5. Update the Activity Aggregator to show we have a new useful link.

Step 3 is where things get tricky. How in all getout do we get webthumb images? There are controls out there you can get, and they are reasonably priced as well. But I decided to keep searching so I could write this one on my own, as it seems like an interesting challenge.

My next thought was to create my own service to do this. There's plenty of code out there, but the easiest way to do this would require some WinForms programming. Don't get me wrong, I LOVE programming WinForms. The problem is I don't want to have to install it everywhere I am at, as I need a service. I could possibly create a Web and Windows service to do this as well, but that seemed overly complex. So I did a search, and I found this, which is a service which does it for you. What's even nicer is that they expose a nice API to use. As of now, the first 100 images a month are free, and after that, the fees are very reasonable. Even though I doubt I will go over 100 images per month, I am so impressed I may pay just to keep the service going.

I was also able to find some c# code to make learning the API fast. I did end up changing it some, but in general it worked very well. You can find it here.

So when the service returns with my image (I used the medium size), I save it to a thumbs directory (had to add write permissions to the directory, or I got an obscure GDI+ error), and call a method on my UsefulLink class to update the record with the thumbnail image. I name the image with the current date and time so that the names will be unique as well.

Finally, once I have downloaded the image and updated the UsefulLink record, I add a call to my Activity class which creates an entry for the Activity Aggregator. As I add more items to throw into the Activity Aggregator, I am considering refactoring things to do some delegate multicasting for all the updates, or perhaps creating a factory where you provide class (should be easy since my business objects share the same base class) or interface, and it knows how to create the activity record instead of making individual calls. That's on my list down the road. :)

Here's what the Activity Aggrgator looks like, with a special Useful Link icon():

 

And here's what the Useful Link section (which has the webthumbs) looks like. I will only be showing 10 at a time to save web page real estate. But I also don't want to lose older links off the page. I am debating now whether to use paging, or just have a smaller hyperlink-only section below the most recent links. I am leaning towards paging, as I have a very neat service I want to implement which makes paging and sorting incredibly fast and easy (more on that someday.. I need to upgrade it to user .Net 3.5 functionality before I post it).

 

All Things | ASP.Net | C# | CSharp | Design | General
Sunday, August 23, 2009 5:28:00 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
Usage of the "var" variable declaration and readability.
All Things | C# | CSharp | Design | General
Sunday, August 23, 2009 7:09:25 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, August 21, 2009
Another interview question of the day -- Access Modifiers
Friday, August 21, 2009 5:06:04 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 19, 2009
Another interview question du jour!
Wednesday, August 19, 2009 8:34:53 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 18, 2009

I've been doing technical interviews for about 5 years now for .Net, and hired a lot of developers in that time. As a result, I have become proficient at quickly assessing a level of technical expertise as well as how a developer may fit within an organization. I will blog another time about what characteristics I look for in a candidate, but for now, I will go through some of the technical questions I ask, answer them, and explain why I ask the question.

Question: What's the difference between an abstract class and an interface

Answer: They have some similarities in that they both define abstract members which have to be implemented. An interface is really just a contract where you are stating "if I implement this interface, I will implement these methods". However, an abstract class can have an implementation, where an interface cannot. An abstract class can also have constructors and field data.

One advantage of an interface is that you can implement more than one interface per class, but you can only inherit from one class.

Note there's a lot more you could talk about with them both (and you don't want to overtalk any question), but the above will demonstrate you have a good knowledge of OOP design, which is what I was looking for. It's surprising how many developers cannot get this question right.

To learn more, here's a good article which discusses them in more detail (more than you'd need to answer the question for sure, but good knowledge to have!)

Tuesday, August 18, 2009 4:02:10 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 17, 2009
I highly recommend the Application Architecture guide from CodePlex.
Monday, August 17, 2009 1:21:50 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, August 16, 2009

Decided to look at my web stats, and when I was looking at the search criteria people were using to find my site, I had to laugh at this one: hate llblgen

I wonder if someone else was at the point of frustration I was. All I can say is this -- don't blog about it!! :) I really ought to categorize this as a "Trick or Tip".

Sunday, August 16, 2009 6:19:47 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, August 15, 2009

I needed to use LINQ to XML to grab some RSS feed information into a BusinessObject I created to save to a database. Here's what I needed:

var activityList = from e in doc.Descendants("item")

                                       select new RubiconPortal.BusinessObjects.Activity

                                       {

                                           ActivityTypeID = ActivityTypes.Blog.Code,

                                           ActivityDate = e.Element("pubDate").Value.RSSDateTime().ToShortDateString() + " " + e.Element("pubDate").Value.RSSDateTime().ToShortDateString(),

                                           ActivitySummary = HttpUtility.HtmlDecode(e.Element("title").Value),

                                           ActivityDetailsURL = e.Element("link").Value

                                       };

 

Since the pubDate comes across in a format which is different than I wanted, I decided to write an extension method called RSSDateTime() to convert to a DateTime, from which I can format any way I want or work with. Here's the method:

 

public static DateTime RSSDateTime(this string date)

        {

            DateTime d;

            if (DateTime.TryParse(date, out d))

            {

                return Convert.ToDateTime(date);

            }

 

            return DateTime.Now;

 

        }

Saturday, August 15, 2009 9:18:49 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I have to get some landscape rock put out before my home owner's association has a cow, but I decided to do some more work on my activity aggregator. Today, I decided to integrate my blog feed into it, so when I post here, it will automatically update this activity on my home page (and soon to be in my developer's area).

Here's what the end result looks (for now).

Doing it was fairly easy with the design I implemented in my last post. My BlogFeed class inherits the BaseFeed class, which means I need to implement the ParseFeed() method. Since the RSS feed from my blog is XML, I was easily able to adapt the same code from my TwitterFeed class to work for this RSS feed (which should actually work for any RSS feed I pass in).

I also created another Extension method (for practice) to convert the RSS feed date time to a C# DateTime object. I will post that code as "Tip of the Day" but I have to give Dan Wahlin credit for it, as I adapted some sample code he provided.

Here's how the RSS feed (aka BlogFeed) uses LINQ to XML for creating my activity object.

    internal class BlogFeed : BaseFeed

    {

 

        public override int ParseFeed(XDocument doc)

        {

            try

            {

                ReturnCode code = ReturnCode.Success;

                if (doc != null)

                {

                    var activityList = from e in doc.Descendants("item")

                                       select new RubiconPortal.BusinessObjects.Activity

                                       {

                                           ActivityTypeID = ActivityTypes.Blog.Code,

                                           ActivityDate = e.Element("pubDate").Value.RSSDateTime().ToShortDateString() + " " + e.Element("pubDate").Value.RSSDateTime().ToShortDateString(),

                                           ActivitySummary = HttpUtility.HtmlDecode(e.Element("title").Value),

                                           ActivityDetailsURL = e.Element("link").Value

                                       };

 

                    foreach (Activity item in activityList)

                    {

                        //We need to check and see if the item exists

                        if (!Activity.CheckEntryExists(item.ActivityTypeID, item.ActivityDetailsURL))

                        {

                            int results = item.Save();

                            if (results != ReturnCode.Success.Code)

                                code = ReturnCode.Failure;

                        }

                        else

                            return code.Code;   //we can break once we hit one we've already logged (for performance reasons

 

 

                    }

 

 

                }

                return code.Code;

            }

            catch (Exception ex)

            {

                ErrorHandler(ex, "An unexpected error occurred in TwitterFeed.ParseFeed() - " + ex.Message);

                return ReturnCode.Failure.Code;

            }

        }

    }

 

My next step will be to integrate some AJAX so when the user hovers over the link, they can see things like the date, more of the topic, etc. I also need to integrate my "Useful Links" dicussion as well.

All Things | ASP.Net | C# | CSharp | Design | General
Saturday, August 15, 2009 9:13:22 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, August 14, 2009

Tonight was a very enjoyable night of coding. I created the first phase of my "activity aggregator". I actually had a more clever name for it, but being tired, it slips my mind right now.

Currently, I post several places.. short updates for on Twitter. Longer discussions end up on here, my blog. I have some other sources I plan on integrating over time, such as links I found useful (similar to Digg, but also where I can place why I found it useful). That means growth, and when it comes to design, it's best to design change into it up front.

The first thing I needed to do was create my table and business object to collect these activities. In my table, I store ActivityDate, what type of activity it was (foreign key to another table -- ActivityType), a brief summary of the activity text, and finally the url someone interested could click on to get more information. The internal members of my activity class look like this:

   15         #region Private Members

   16 

   17         private int activityID;

   18         private int activityTypeID;

   19         private string activityDate;

   20         private string activitySummary;

   21         private string activityDetailsURL;

   22 

   23         #endregion

 

Each private member has a publically exposed property.

 

Most of my activities will have XML feeds, such as the RSS feed of my blog, and the Twitter API. Therefore, I enforce a similar implementation by creating an abstract base class, called BaseFeed, which looks like this:

    1 using System.Xml.Linq;

    2 using RubiconPortal.Common;

    3 

    4 namespace RubiconPortal.BusinessObjects

    5 {

    6     internal abstract class BaseFeed : BaseClass

    7     {

    8 

    9         public abstract int ParseFeed(XDocument doc);

   10 

   11     }

   12 }

 

So now I have a "contract" that I need to use to have a similar method for any activity I want to log. I could have used an interface for this, since there's no true implentation here, and I may refactor it later to do so, but I do have some ideas where I may want to provide some implementation, so that's why I chose an abstract class.

 

So the first item I wanted to do was implement capturing my Twitter posts in this activity, since I currently don't have a way to capture and post them on my site. I will add the rest of the activities later. In a previous post, I described how I took the Yedda Twitter API and modified it to return XDocuments, and here's another chance to take advantage of that change with LINQ.

 

When I post to my Twitter feed, I want to make sure my home page automatically reflects this activity. So I implement a TwitterFeed object, which implements the BaseFeed method ParseFeed. Using LINQ to XML, I pull out the pieces of the response I want, and populate the public properties of my Activities class, then save my activity. Here's what my TwitterFeed class looks like:

 

    1 using System;

    2 using System.Linq;

    3 using System.Web;

    4 using System.Xml.Linq;

    5 using Rubicon.Common;

    6 using RubiconPortal.Common;

    7 

    8 namespace RubiconPortal.BusinessObjects

    9 {

   10     internal class TwitterFeed : BaseFeed

   11     {

   12         public override int ParseFeed(XDocument doc)

   13         {

   14             try

   15             {

   16                 if (doc != null)

   17                 {

   18                     var activityList = from e in doc.Descendants("status")

   19                                        select new RubiconPortal.BusinessObjects.Activity

   20                                        {

   21                                            ActivityTypeID = ActivityTypes.Twitter.Code,

   22                                            ActivityDate = (e.Element("created_at").Value.ParseDateTime()).ToShortDateString() + " " + (e.Element("created_at").Value.ParseDateTime()).ToShortTimeString(),

   23                                            ActivitySummary = HttpUtility.HtmlDecode(e.Element("text").Value),

   24                                            ActivityDetailsURL = "http://twitter.com/" + e.Element("user").Element("screen_name").Value

   25                                        };

   26 

   27                     foreach (RubiconPortal.BusinessObjects.Activity item in activityList)

   28                     {

   29                         item.Save();

   30                     }

   31                 }

   32 

   33                 return ReturnCode.Success.Code;

   34             }

   35             catch (Exception ex)

   36             {

   37                 ErrorHandler(ex, "An unexpected error occurred in TwitterFeed.ParseFeed() - " + ex.Message);

   38                 return ReturnCode.Failure.Code;

   39             }

   40         }

   41 

   42     }

   43 

   44 }

 

Within the ParseFeed method I am using LINQ to XML to populate my business object calling the save() method to write it to the database. As you can see, using LINQ to XML can be a lot simpler than using XML/XPath. Once in the database, I can query it in my user control, and display it on my home page here.

 

Now, when I make my Twitter post, all I need to do is take the XDocument the Twitter API returns, and pass it into the ParseFeed method, which looks like this...

   35                     //Post my tweet to Twitter

   36                     TwitterAPI twit = new TwitterAPI();

   37                     XDocument doc = twit.UpdateAsXML(Settings.TwitterUserName(), Settings.TwitterPassword(), txtPost.Text);

   38 

   39                     //Save it to the activity table for displaying the activity

   40                     TwitterFeed feed = new TwitterFeed();

   41                     feed.ParseFeed(doc);

 

Simple and neat! Now when I implement it for my blog, it will be just as quick and easy!

 

Props go out to this post I snagged an extension method for formatting the Twitter posting date to something a human can use (and my C# class can use to manipulate and save!)

 

 

 

Friday, August 14, 2009 7:40:31 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 12, 2009
Some tools I downloaded today which appear VERY useful, and touching on the ORM topic.
Wednesday, August 12, 2009 6:31:11 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 11, 2009

Tonight I didn't get as much time to work on the site as I would have liked, so I focused on getting the admin pages up on the production server so I could do some "behind-the-scenes" work remotely. This required some security, which I started last night, but the data migration for that was a bit more daunting, so I needed to finish it tonight. While the authentication providers and controls do handle a LOT, it has an interesting learning-curve, and deployment can be a challenge as well. All-in-all, it sure beats writing all that code by myself.

I tried to use a lot of caching and cached settings to help improve the performance on certain pages, especially my client list. On my admin pages, I made sure to create a means to reset that cache without having to do a complete server reset. Actually, the same approach I took would work well for high availability sites, as the method I used to complete this would not require a server reset to re-load systems. When I was int he banking industry, high-availability was a huge issue, and simple config changes meant waiting for a scheduled system outage or worse, an emergency outage. When I redesigned that site, that was one of the top priorities I had.

It occurred to me how much time it takes to set up the infrastructure of a site: master pages, common libraries, configuration files, CSS, etc. Once those are done, if done properly, the rest of the site should go fast. One thing I have found to speed that up was the use of Visual Studio Project Templates. Combined with code generation like CodeSmith, you can really generate web sites extremely fast, and get on to coding the "fun" items. I will write about both of those in the future (CodeSmith and Project Templates) once the site is stabilized.

Tomorrow night may not have a lot of development, as my parents will be in town. Later this week, I will be coding my next control: the activity feed. When posts and feeds are made or read, this control will snag it, and place a brief "teaser" on the home page.

Tuesday, August 11, 2009 6:05:59 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 10, 2009

I finally managed to get my client list online today. From a technological standpoint, it was pretty straight forward. I store the information in the database, and use my CodeSmith templates to create a class for extracting the data, and then use a Repeater to present the information in a table format. I still need to make some changes to it, but all in all, it works well. Since the data won't be changing often, I did cache the data to make it come back faster.

I started working on security for my Administration pages. I need to get that set up before I can activate the admin pages, but I have run into some issues getting it all configured. I ran into this once before with the ASP.Net forms authentication security provider, but this time is a little different, as I only want to secure one folder. Certainly not too difficult to do, but not as easy as I would have hoped either.

Once I get the security and login page worked out, I'll begin working on my "links" page. The idea here is that when I blog, or post to twitter, or a few other ideas I have, it will update the dark blue control on the home page with a summary and hopefully someone will click through to get the rest of the details. This should be fairly straightforward to do. Since most of the services respond in XML, I'll just use a factory method to instantiate the proper object, which will know exactly what information I want to extract from the XML feed. As I add more items I want to track, I will simply have to implement the same interface and it will plug right in to my "updater". For the items which return XML (e.g. RSS or Twitter), I will use LINQ for XML to grab just want I want and populate the data right into my classes.

Which brings up a point...

I could probably do this almost as easy with XPath. When does it make sense to move to the more "sexier" technology as opposed something proven and works well? For example, a lot of times, when a new technology is rolled out, it tends to be buggy and some of them historically have not performed well (e.g. early XML for those who have been around a while). All things equal, when does it make sense? Just a rhetorical question, but one I got hit with recently.

I was in a technical interview for a job I wasn't planning on taking (drive was too far -- the company I was representing knew this as well, they just wanted me to be on their radar for the future). I was asked about a particular implementation of the new List object. Honestly, I know how to use the List object, and he was asking about some of the internals I really hadn't needed to know.

If I was having performance issues, I would want to know, and then I would look into it further. In this case, I was able to provide at least 4 other reasonable implementations based on the criteria I was given, yet, I still couldn't get the "sexy" answer he was looking for. At what point does it really matter? For my part, I didn't like NOT knowing, and I did look it up when I left, but in the big picture, when does it become relevant? In my book, the practical solution to a relevant problem always supercedes technical "sexiness".

All Things | ASP.Net | C# | CSharp | Design | General
Monday, August 10, 2009 5:58:40 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, August 07, 2009
A plug for my company, Rubicon Computing Solutions, LLC.
Friday, August 07, 2009 6:02:11 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 05, 2009
Using LINQ to XML to work with the Twitter response, and modifying the Yedda Twitter API wrapper.
Wednesday, August 05, 2009 6:34:05 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 04, 2009

Note: For visitors of your site, this entry is only displayed for users with the preselected language English (United States)/English (United States) (en-US)

How the VS2008 IDE is very helpful to conditional compilation, and also how the site is coming along

Tuesday, August 04, 2009 6:15:10 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, August 02, 2009

As the main site is developed, I'll detail what decisions I used to create the site, then a high level overview of how I designed it. Just a warning though, some of the decisions will seem very arbitrary, as they were. I made them simply because working on your own site gives you a luxury of trying things you normally can't do with a client. In my case, a lot of my decisions will be over-engineered, because I may want to re-use them later.

Of course, the first thing I had to come up with was an overall site layout. I won't go into that here, as one thing I will never profess to be is a layout guru. I got a decent design, and I set them up as a master page so the rest of the site development will go easy. I used VS2008 and C#, and began implementing AJAX where it made sense. For example, there's a control which updates the current time every 30 seconds or so, so I could use the update panel and timer control.

The first real functionality I wanted to add was a link to this blog. So I created a user control, and placed it on the front page. However, I do plan on posting a lot more here, so I knew it wouldn't be feasible to show every post, so I decided to limit it to the latest three posts. I wanted to display the title, the date and the first bit of the post to hopefully catch a reader's attention.

But reading from a feed from sites at two different hosting providers can be tricky. Not from a security standpoint, as RSS feeds are open, but more from a performance standpoint. Anyone coming to my portal site should be able to see the latest posts, and quickly. The fastest way of doing this would be to create a Windows service which periodically reads the feed, and stores the information in a database. However, I am not sure I would be able to install a Windows service on my service provider's server. So......

What  I can do however is read the feed, and place it in cache. Periodically, I can expire the cache and re-load it, and unless you are the unlucky soul to have to wait while it loads, the majority of the users will have a quick response. For that poor soul who waits while cache is refreshed, I used Ajax and the UpdateProgress control to provide some visual feedback that the page is doing something.

The rest was pretty straightforward. I either request the XML from the RSS feed (or cache), and use XSLT to display it. It's been a while since I have used XSLT, but there is a lot of potential there, I expect I will be using a lot more of it in future controls. I created the class generically so that I could pull any RSS feed I wanted from it as well.

One great use I found for XSLT was on a high-availability web site which sent a lot of emails. We wanted to be able to change the email format frequently without bringing the site down. Using XSLT, we could change the email template files any time to create very nice HTML based email messages. I read a great article recently about calling C# functions in your XSLT templates using extension methods, which I plan to use extensively, as C# is my main domain. Maybe I will use them... I say that as I really would like to improve my XSLT skills, as I think the technology is highy underused in the .Net world.

So now I am playing with Twitter feeds and getting the rest of the site content set up. I also used the AJAX popup control to help prevent any 404 errors as I complete the functionality. If you've been putting off using the AJAX Control Toolkit for some reason.. STOP! The amount of functionality these controls offer is amazing, and you can't beat the price.

That's it for now! If you want more details on how I accomplished this or some sample code, just send me a comment. Upcoming posts will address the development of the rest of the site, along with some major wins recently using CodeSmith.

 

All Things | ASP.Net | C# | Design | General
Sunday, August 02, 2009 3:54:16 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

The past three years have been spent more managing teams of developers than actually doing development. On my current gig, I have gotten more of an opportunity to get back into the code, and I have to say, I mhave missed it immensely.

As a result, I have started doing coding purely for myself, and I have to say it has been immeasuably enjoyable. So I put my company's website back online, but this time it uses AJAX, RSS feeds, and soon, Twitter!

It's been an interesting and fun hiatus from pure coding, but now I am really looking forward to updating my skills again, and writing about it along the way.

This post will be the first "real" test of my onsite RSS reader. So in a bit, it should appear on the front page of my all new company portal site... Rubicon Computing Solutions!

Sunday, August 02, 2009 1:30:11 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, June 13, 2006
New Data property of the Exception class is quite useful!
Tuesday, June 13, 2006 4:42:38 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, May 16, 2006
Get the name of the current db in t-sql
Tuesday, May 16, 2006 4:38:30 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, April 28, 2006
A new blog...
Friday, April 28, 2006 4:38:06 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, March 27, 2006
A humorous story I remember from my adventures as a consultant...
Monday, March 27, 2006 4:49:48 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, March 22, 2006
Easy solution..
All Things | C# | General | Tools
Wednesday, March 22, 2006 11:00:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
Re-inventing an outdated but very useful wheel....
All Things | ASP.Net | C# | CSharp | General | Tools
Wednesday, March 22, 2006 3:44:55 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 21, 2006

Is it just my installation, or is WinCV missing from the latest version of .Net? Granted, I can still use the old WinCV by changing the config file, but why was such a useful tool pulled from VS2005?

If you've never used WinCV, check it out for VS2003 and prior version. It essentially lets you search the framework for a certain keyword. For example, if you want to find out which namespace "Registry" is in, type it in, and see the entire implementation. By using the configuration file, you can add additional assemblies for WinCV, to search your own libraries or those of third party vendors.

 

Tuesday, March 21, 2006 1:48:01 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, March 17, 2006

I've been playing a bit of poker recently, and having mixed results. Earlier this year, I was on a tear, and couldn't lose. Lately though, it's been a bit dry. I played in a tournament on Sunday at a local casino, and finally made the final table again, and even did ok in te cash game leading up to it.

Tonight was a humorous night though. I decided to play again, as I am in the running for a finals tournament at the casino I placed on Sunday. First, I played against a handicapped player, and we came up with a device to help quadraplegics to play poker with less assistance than it normally takes. Now I just have to find the parts and see if I can put it together, as it looks like a very viable solution to help him. But secondly, I have to say tonights tournament was the "worst" I have ever had. Although I managed to stay alive for 2.5 hours (mainly due to the lack of playable hands or situations), I did not win a single hand. However, I DID manage to chop one, so I will count that as 1/2 of a hand, but all I won were half the blinds. If you count the cash game I played prior to the tournament, I think you could take that losing streak to 4 hours of not winning one hand. Fortunately, losses were minimal, as the hands I was starting with were poor quality, and I just rode out the blinds. I think that is the longest I have ever gone. What a test of patience!

Such is poker...

Friday, March 17, 2006 5:39:58 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 16, 2006

Previously, I discussed how I worked around a firewall issue where the HTTPS port was re-mapped, and the return URL was different than the request URL as a result of that remapping. So I trudged on, and hit a real stumper. Here’s the new issue:

 

The underlying connection was closed: Could not establish secure channel for SSL/TLS. Inner Exception: The function completed successfully, but must be called again to complete the context

 

I ran across Jan Tielen’s blog post (http://weblogs.asp.net/jan/archive/2004/05/08/128394.aspx) where he provided a code snippet to override the GetWebRequest method in the Reference.cs file. I implemented it, and it worked great --- on my development machine! However, when rolled out to the same test environment, the problem remained. However, I modified it futher, and got it to work..

 

/// <summary>

/// Set web request properties here

/// </summary>

/// <param name="uri">uri </param>

/// <returns></returns>

protected override System.Net.WebRequest GetWebRequest(System.Uri uri)

{

   System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)WebRequest.Create(uri);

   webRequest.AllowWriteStreamBuffering = true;

   webRequest.KeepAlive = false;

   return webRequest;

}

 

Sort of. When I tried to use DIME with the above code, it gave me an error “Client found response content type of '', but expected 'text/xml'”. That was not going to work. I found some more code, and it seemed to work great once again, until I tried to make a DIME call. Here was that attempt.

 

protected override System.Net.WebRequest GetWebRequest(System.Uri uri)

{

     WebRequest request = base.GetWebRequest(uri); ;

     if (requestPropertyInfo==null)

         requestPropertyInfo = request.GetType().GetProperty("Request");

     

     HttpWebRequest webRequest = (HttpWebRequest)requestPropertyInfo.GetValue(request,null);

     

     webRequest.KeepAlive = false;

     webRequest.ProtocolVersion = System.Net.HttpVersion.Version10;

     return request;

}

 

Once again, it worked fine during my WSE calls, but failed when trying to use DIME attachments with the following error:  found response content 'application/dime', but expected 'text/xml'

 

To save any readers some time, I will go through everything I tried to resolve the problem, and finally, how I ended up resolving it. Here’s the items which didn’t work:

 

-- tried setting the SoapActor

-- tried turning off the Document protocol

-- tried setting the request and return URI

-- tried overding the GetWebRequest function a few different ways

-- tried using wsdl instead of asmx in setting up the Web Reference

-- tried setting the URI target/destination seperately

-- moved web service to the same machine as the calling web site (but still had to make an external call)

-- turned on tracing input and output and analyzed the logs created by WSE 2.0

 

So what finally worked? I ended up abandoning DIME, and encoded the file as a string, and passed it as an element of my XML. Here’s the code to encode the file as a string.

 

/// <summary>

/// Encodes the file in a Base64 string format.

/// </summary>

/// <param name="file">Name of the file.</param>

/// <returns></returns>

private string EncodeFile(HtmlInputFile file)

{

      try

      {

            if (file.PostedFile.ContentLength > 0)

            {

                  byte[] fsBytes = new byte[file.PostedFile.ContentLength];

            System.IO.Stream fileStream = file.PostedFile.InputStream;

            fileStream.Read(fsBytes, 0, file.PostedFile.ContentLength);

 

            return Convert.ToBase64String(fsBytes);

            }

            else

                  return String.Empty;

      }

      catch (Exception ex)

      {

            //Handle the Error

            return String.Empty;

      }

}

 

What a trip it was to get there, but the resulting service has performed well, and I don’t have the issues I had with DIME. Don’t get me wrong, DIME worked great. But deployment of the web service in a secure environment proved to be quite a challenge. If you need more detail in resolving your issue, feel free to leave a comment or shoot me an email, and I will be glad to save you some of the pain I had to go through!

Thursday, March 16, 2006 5:19:42 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 14, 2006

Just a little tip, as I didn't read the error message generated as closely as I should have. I was working this weekend on the Microsoft Code Template for Building a Provider Based Feature and was migrating some existing libraries I had for VS2003 to take advantage of the features in VS2005.

First, let me say I love things in VS2005 like Generics, and the implementation of the Provider Model. I was migrating my data access libraries and error handling libraries, and was setting up some tests in nUnit as part of ongoing testing. Although I haven't changed my data and error handling models in a long time, I figured it was a great design idea to be able to change them dynamically using the Provider Model.

To make a long story short, I was running my tests for the data library, and when I invoked my Data Access classes, I was getting a "TypeInitializationException" error. I checked and double-checked my configuration file, and it appeared to all be correct. I looked at the InnerException, and it didn't seem to be much more help. However, I went further to look at the InnerException of the InnerException, and there's where I found the solution. The Rosetta Stone?

  • Only one <configSections> element allowed per config file and if present must be the first child of the root <configuration> element.

A quick check indicated that I hadn't made the configSection the first element. Doh!

So there are a few lessons to learn here. 1) Make sure your configSections is first (normally not a problem, just a cut and paste issue here) and 2) Make sure you dig REAL deep into the InnerExceptions for the details and 3) the new Visualizers in vs2005 were too cool and very helpful.

Hats off to the VS2005 IDE team! It's spawned a few visualizers I can think of, so if time permits in the future, I will be publishing those right here!

Tuesday, March 14, 2006 5:52:31 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 09, 2006

At my current client, security is taken to a whole new level, which is a good thing. But as a result, sometimes there is more of a challenge to resolve issues you may not normally encounter. For example, I was tasked with writing a web service which would facilitate file transfers of documents and images from a web page (and Windows client), store them on a secured server, and serve them up to an authenticated user on the internet. To do so, we have to deal with proxy server issues and firewall issues.

After writing and testing the web service locally, I deployed it to our production server. Locally, it all worked fine. However, when I deployed the web portion of the application to our test server outside our intranet, the real fun began. The next several posts I will discuss the problems I encountered, and how I ultimately resolved the issue. Hopefully this will help any readers out there who have a similar issue, as well as become documentation for the process I used so I can later reference it.

The first issue I saw was the following error:

The <To> header must match the value of an incoming message's HTTP Request Url if the soap receiver does not have an actor name.

I'd love to give the person I found the solution at credit, but it's been such a long time I can't find the original document I used. I modified the solution to make it a little more "generic" so that the web service can be moved without requiring a recompile of the application.

First, you'll need to locate the Reference.cs file for the web service reference(for C# users. Reference.vb is the similar file for VB.Net, but all code here will be in C#). In this file, add the following reference:

using Microsoft.Web.Services2.Addressing;

Next, locate the consructor for the WSE portion of the Reference.cs. In this case, mine will be FileServiceWse(). Here's the code you'll need to replace the this.Url reference already in there.

public FileServiceWse()

        {

            //these two setting are the <TO> and Response URLs. For example, in our case the response was

            //coming back with the redirected port appended to the url.

            //The Web service <TO> looked like https://mycompany.com/FileService/FileService.asmx

            //but the response was https://mycompany.com:1234/FileService/FileService.asmx

            //The endpointreference call to the Destination tells the application to expect the return url to look differently than the

            //<TO> reference

            string urlSetting = System.Configuration.ConfigurationSettings.AppSettings["FileService"];

            string urlReturnSetting = System.Configuration.ConfigurationSettings.AppSettings["FileService.ReturnURL"];

            if ((urlSetting != null) && (urlReturnSetting != null))

            {

                Uri sourceUri = new Uri(urlSetting);

                Uri returnUri = new Uri(urlReturnSetting);

 

                this.Destination = new EndpointReference(sourceUri, returnUri);

            }

            else

            {

                if ((urlSetting != null))

                {

                    this.Url = string.Concat(urlSetting, "");

                }

                else

                {

                    //this is the default URL of the file service if all else fails.

                    this.Url = "https://mycompany.com/FileService/FileService.asmx";

                }

            }

 

        }

 

What this code does is set the Destination property (if the FileService and FileService.ReturnURL settings are placed in the web.config file) to expect a different response than the requested web service URL. In our case, since our request was going through a firewall which remapped the ports, we had a port attached to the url for our web service which triggered this error.

The code also has failover. If I forget to make the settings, it will try the original URL reference. In my case the call won't work, but I believe in at least attempting to code some failover when human error can take place in moving files, etc.

But this only solved one of the many challenges I encountered in deploying this web service. Stay tuned for the next resolution to tricky WSE issues!

Thursday, March 09, 2006 4:12:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

It's not a record for longest time between posts, but it sure has been a while. I finlly got off my butt and upgraded das Blog to the latest version, and enabled comments again. So now maybe it will be worthwhile to begin blogging again!

The past few months have been interesting to say the least. I have a catalog of things to post about, such as solving some bizarre web service issues with DIME (well, solution is not quite the word... a workaround is more like it) as well as beginning the trek into VS2005.

So if there's anyone still out there readin this, I do have a ton to write about, now lets see if I can find the time to do it!

Thursday, March 09, 2006 4:52:50 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, December 09, 2005
XBox 360 not working? Then sue!
Friday, December 09, 2005 10:01:47 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, October 07, 2005
..or why MS has once again dropped the ball on it's core developer community.
Friday, October 07, 2005 4:57:27 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, September 20, 2005
"Internal Query Processor Error: The query processor could not produce a query plan. Contact your primary support provider for more information" when passing in C# DateTime value...
Tuesday, September 20, 2005 11:50:34 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, August 05, 2005
spammers!
Friday, August 05, 2005 2:33:34 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 20, 2005
When you have to eat your hat...
Wednesday, July 20, 2005 9:31:12 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, July 19, 2005
I hate LLBLGen, ask me why!!
Tuesday, July 19, 2005 5:49:51 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  | 
# Friday, May 27, 2005
(and maybe why Extreme Programming (XP) is also bad?)
Friday, May 27, 2005 6:28:46 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
Need a good developer?
Friday, May 27, 2005 12:33:35 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
Tired of cutting and pasting? Try CodeSmith...
Friday, May 27, 2005 12:19:32 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, April 23, 2005
What the $*#(U$(? Where did the wse version go?
Saturday, April 23, 2005 9:36:27 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, April 14, 2005
I am joining the fray....
Thursday, April 14, 2005 5:49:54 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, April 04, 2005
How to get them to reappear...
Monday, April 04, 2005 7:28:35 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, March 21, 2005

Let's talk resume's for a minute. You want that interview don't you? Well, sometimes all you have to get you there is your resume (although personal reference is the best way if you can get it, an area where networking and doing quality work can help).

There's a million places on the internet to help you decide how to structure your resume. I have only gotten one criticizm from my resume, and I am not sure if it's the content or the structure which works best. But here's a couple of pointers which I think have helped out my resume.

  1. Place a logo of any certifications you have if available (e.g. MCSD). These are real eye catchers. Make the images small though..
  2. Place your specific skills separate from your experience, preferably near the top. This makes it easy to survive the first pass from the recruiter/manager.
  3. Sell yourself! Research “power“ words and make any experience descriptions short and chock full of those words.

Now, there's a few easy tips of what to do. I have been helping staff for years, and here's some of the gems I have seen.

  • Horrible writing and spelling.
  • Obviously exagerated skills and experiences (4 years experience, 10 years at a certain skill)
  • Never say you are an expert at anything, even if you are. Humility goes a long way, and if the interviewer knows more, you'll be humbled by them, as I witnessed in the past week.
  • Use nice paper if submitting a hardcopy (I received one handwritten on a partial piece of paper -- I kid you not)

It's not tough... just use some common sense!

Monday, March 21, 2005 3:11:00 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, March 19, 2005
OK, so now you know wht might be asked.. how not to blow it.
Saturday, March 19, 2005 12:14:50 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, March 18, 2005
WTF? Poor documentation...
Friday, March 18, 2005 9:15:58 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [4]  | 
# Thursday, March 17, 2005
wow... what was that? Some observations from helping with some technical interviews.
Thursday, March 17, 2005 8:19:01 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Wednesday, March 16, 2005
When you need to uniquely identify a file using the time and date stamp, use this!
Wednesday, March 16, 2005 3:26:57 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Friday, March 11, 2005

Someone asked me today if I knew that you couldn't use GETDATE() in functions in SQL Server. Well, I did, so I dug out this solution I had found a while back, and decided to post it, since I am sure others have come across the same issue.

Basically, you use a view to do the work for you... here you go!

CREATE VIEW Function_Assist_GETDATE

/********************************************************
*
* A view to return one row, with one column, the current
* date/time from the built-in function GETDATE().  This
* view allows a UDF to bypass the restriction on access to
* the non-deterministic getdate() function.
*
* Attribution: Based on a newsgroup posting in by Mikhail
*   Berlyant in microsoft.public.sqlserver.programming
*
* Common Usage:
DECLARE @dtVar datetime
select @dtVAr = [GetDate] from Function_Assist_GETDATE
**********************************************************/

AS
    SELECT getdate() as [GetDate]

GO

GRANT SELECT on Function_Assist_GETDATE to PUBLIC
GO

Friday, March 11, 2005 9:45:00 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, March 09, 2005
Exception handling analyzed...
Wednesday, March 09, 2005 5:47:50 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 03, 2005
Tips of the day just aren't...
Thursday, March 03, 2005 11:07:53 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, December 31, 2004
Clearing up the confusion when you need the return value from an insert.
Friday, December 31, 2004 3:25:39 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, December 30, 2004
Finding all tables where a field exists in SQL Server
Thursday, December 30, 2004 6:09:49 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, December 28, 2004
How to format a date to a particular format...
Tuesday, December 28, 2004 5:07:14 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, December 27, 2004
How to quickly find out which control caused the postback
Monday, December 27, 2004 10:19:36 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [4]  | 
# Tuesday, December 21, 2004
How to step through your client side code
Tuesday, December 21, 2004 9:26:19 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Monday, December 20, 2004
The vb function in C#
Monday, December 20, 2004 9:13:55 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, December 18, 2004
Just a tip to remind myself
Saturday, December 18, 2004 9:55:17 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, December 15, 2004
A brief look into the System.Diagnostics namespace...
Wednesday, December 15, 2004 8:15:13 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [4]  | 
# Saturday, December 11, 2004
A costly mistake to forget...
Saturday, December 11, 2004 6:29:51 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, December 10, 2004
Too tired to code, so I will at least post a link or two..
Friday, December 10, 2004 2:30:27 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Wednesday, December 08, 2004
How to cast to a specific type if you have the string value of the type
Wednesday, December 08, 2004 2:49:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Monday, December 06, 2004
Quick fix for a "catastrophic" problem!
Monday, December 06, 2004 4:44:29 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, December 03, 2004
If you own a TabletPC, gotta have this!
Friday, December 03, 2004 3:23:38 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, December 02, 2004
Well lookie what else it can do!
Thursday, December 02, 2004 5:42:28 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, November 30, 2004
Let's work with an enum today!
Tuesday, November 30, 2004 5:11:10 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
A useful port from something in the old VB6 days...
Tuesday, November 30, 2004 5:05:16 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, November 29, 2004
Save the day!
Monday, November 29, 2004 6:16:26 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
Hot keys and aliases, oh my!
Monday, November 29, 2004 4:36:57 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, November 27, 2004
A quick function to convert an integer to a Roman numeral
Saturday, November 27, 2004 4:25:01 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, November 25, 2004
What I am currently reading, technology-wise....
Thursday, November 25, 2004 5:51:47 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Wednesday, November 24, 2004
My first experience with Test Driven Development
Wednesday, November 24, 2004 4:10:05 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, November 23, 2004
Follow me as I configure a client in automated builds
Tuesday, November 23, 2004 9:47:25 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, November 21, 2004
How to configure log4net to save entries into the database
Sunday, November 21, 2004 4:05:01 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Friday, November 19, 2004
How to make an ASP.Net page expire
Friday, November 19, 2004 2:40:51 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 18, 2004
First part in a series on developing a filter control to demonstrate UI Abstraction and Component Based Development
Thursday, November 18, 2004 5:14:36 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, November 17, 2004
How to break on an error in ASP.Net
Wednesday, November 17, 2004 3:29:26 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Thursday, November 11, 2004
I start a "new" project in a little over a week.
Thursday, November 11, 2004 5:13:29 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
Changing the look of thinks client side dynamically...
Thursday, November 11, 2004 5:05:03 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, November 10, 2004
How to search all those assemblies and find just what you need...
Wednesday, November 10, 2004 4:47:53 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, November 09, 2004
CodeLib from fish
Tuesday, November 09, 2004 5:34:42 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, November 08, 2004
Allows you to capture the click, dblclick, etc to make a normal form control read only.
Monday, November 08, 2004 4:47:19 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
How to dynamically change the EntType of an HTML form...
Monday, November 08, 2004 4:40:15 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
Monday, November 08, 2004 12:48:09 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  |