Another "Late Pass" series entry. I've just recently started using extension methods and seeing how useful they can be. Extension methods have been pretty fun to write so far. It's nice to find yourself wanting a piece of functionality and then having the power to now do it.
My first extension method deals with Guids. I tend to use Guids a lot and there is no real way to convert something to a Guid. Let's say you have a QueryString value that is a unique identifier (i.e. Guid) and you want to check for it, convert it to a Guid, then do something with it (i.e. retrieve employee information, etc...) I've found that to do this I'd need to some variation of the following:
string
s = Request.QueryString["Guid"];
Guid guid == Guid.Empty;
if (!string.IsNullOrEmpty(s))
try
{
guid = new Guid(s);
}
catch (FormatException)
{
guid = Guid.Empty;
}
if (guid != Guid.Empty)
{
// do stuff with Guid g
}
Enter my first extension method: IsGuid(). This provides a less verbose method of doing business.
if (s.IsGuid())
{
Guid guid = new Guid(s);
// do stuff with guid
}
There is another option:
Guid guid = Request.QueryString["Guid"].ConvertToGuid();
if (guid != Guid.Empty)
{
// do stuff with Guid
}
Here is the code for the extension methods. First you will you need a RegularExpression for the format of the Guid. That's easy enough as Guids have the same format 8-4-4-4-12 (would provide a link to where I found this regular expression but I forgot where I got it 8^( )
private
static readonly Regex _guidRegex = new Regex(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled);
Now the actual methods:
public
static bool IsGuid(this string value)
{
return !string.IsNullOrEmpty(value) ?
_guidRegex.IsMatch(value) : false;
}
public static Guid ConvertToGuid(this string value)
{
return string.IsNullOrEmpty(value) ? Guid.Empty :
(_guidRegex.IsMatch(value) ? new Guid(value) : Guid.Empty);
}
Again, I apologize for the line breaks. I need to implement a new CSS layout. By implement I mean find a free one that isn't a complete mess.
I'll be posting more extension methods in the future. Too bad I missed the bus a couple of months ago!
Easy.
Tags:
.NET,
C#,
Code
I've had the pleasure of working on some code from overseas lately. What a long strange trip it's been. I'd like to get into the mind of some of the developers who pump out this code one day. It'd be nice to ask why things were done the way they were.
This current project utilizes separate projects for Data Access and Business Logic in the form of class libraries. Great. What a good practice. I was digging around in the Data Access Layer this morning trying to add some functionality that a client requested. Just as I'd expected there were calls to SQL 2005 stored procedures. I knew the names of the 2 stored procedures I needed to change and login to the server and make the necessary changes. I typed the column-name I needed so that it was now the first column to be selected, leaving everything else as is. I compile the project, run it, navigate to the page I need to test the newly-added functionality and get greeted by a nasty InvalidCastException. Awesome!
Wow, a strongly-typed, encapsulated application and I get an InvalidCastException. Hmm, I wonder. I did a little more right-click -> 'Go To Definition''ing and found the following gems:
using
(SqlDataReader reader = SQLHelper.ExecuteReader())
while (reader.Read())
foo = new Foo();
foo.FooId = reader.GetInt64(0);
if (!reader.IsDBNull(1))
foo.DecimalProperty = reader.GetDecimal(1);
if (!reader.IsDBNull(2))
foo.StringProperty = reader.GetString(2);
// continue for all 24 columns ...
list.Add(foo);
Wow. The worst possible way of setting your properties: relying on zero-based ordinals. The call to the SqlDataReader's GetInt64 method explains my InvalidCastException. The fact that there are 24 columns in this subset of data and this was the best way to set public properties is staggering. Is it that much harder to actually use the reader's column name approach?
foo.FooId = (int) reader["FooId"];
A lot of people give me a hard time for using Reflection because it can be kind of heavy-handed at times (and I totally agree). This is definitely one of those times where I would use it: Data Access. Time to play "I bet I can code that in 6 lines or less".
while
(reader.Read())
{
T instance = Activator.CreateInstance<T>();
foreach (PropertyInfo property in typeof(T).GetProperties())
property.SetValue(instance, reader[property.Name], null);
list.Add(instance);
}
What are your experiences (if any) with working with outsourced code?
Tags:
.NET,
C#
Have any of you had any problems with ReSharper 3.0.2 when working on remote websites? For some reason ReSharper has been acting buggy when I open a remote website. For instance, sometimes I have intellisense and other times I don't. Let's say I want to add a class to the project. Usually I will right-click, add new item, and when that class is displayed I see that I can press CTRL+ALT+O to optimize usings. Well now I don't have intellisense AT ALL! In order for my intellisense to kick in I need to build the website, close the project, and then re-open the website. That is enough for intellisense to kick back in some of the time.
I can't bare the thought of not using ReSharper so hopefully someone can clue me in as how to solve this little issue.
Another weird behavior is that code analysis is screwed up. In creating a user control I am inheriting from a base class. Code analysis tells me that I am in fact incorrect but when I compile / run the application there are no errors and everything is as it should be. I could turn off Code Analysis but this is a route that I do not want to take.
Any suggestions?
Tags:
.NET,
Tools
Pretty basic stuff but can be very useful. I've been working lately on a scheduling application (2.0) and just finished a user welcome screen at about 1:00am on this lovely Thursday night. The idea is that users login to the system and on their homepage are shown a calendar. This calendar should show the current month (or selected month) and visually display what days the user is scheduled for a certain task. The dates are entered by administrators and stored in a SQL 2005 database.
There are two important methods to use: OnDayRender and OnVisibleMonthChanged.
85% complete pseudo-code. The accountNumber is arbitrary. What you don't see is the calendar control in my .aspx page wired up to these handlers.
List
<DateTime> _dates = new List<DateTime>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
_dates = Schedule.GetDates(accountNumber, calendar.TodaysDate);
}
protected void OnDayRender(object sender, DayRenderEventArgs e)
{
if (_dates.Contains(e.Day.Date))
e.Cell.BackColor = Color.CornflowerBlue;
}
protected void MonthChanged(object sender, MonthChangedEventArgs e)
{
_dates = Schedule.GetDates(accountNumber, e.NewDate);
}
Now when the user clicks the next and previous month links a new list of dates will be populated and the calendar will display accordingly.
Result

This is very basic stuff but highly effective. The current application I'm working on displays / functions far beyond the quick demo screenshot I posted. I give users the ability drill down from the calendar day (SelectionChanged) to view a more detailed view of the current task. Users can even switch tasks with another user or post up a task to be taken over by someone else. Think trading and picking up shifts at a restaurant.
If there is an easier way to accomplish this please let me know.
Tags:
.NET,
C#
Andrew Robinson gave a great presentation at our monthly .NET User Group meeting last Wednesday night on extending ASP.NET Web Controls (System.Web.UI.WebControls). Driving home from the meeting I started thinking of how I could extend controls for my benefit. The first arena was that of input validation for web forms. Adding input fields (textboxes) to a form and then having to associate a RequiredFieldValidator for said textbox gets real old, real fast. Think of a form with 20 fields. That's 20 RequiredFieldValidators. That's 20 of this:
<
asp:TextBox ID="textEmailAddress" runat="server" /><asp:RequiredFieldValidator ID="requiredEmailAddress" ControlToValidate="textEmailAddress" ErrorMessage="Required!" runat="server" />
Doesn't look too fun does it? I thought of creating a control that had the option of being a required field and if so, specifying a message to display. So now all I have to do is type this:
<
asp:RequiredTextBox ID="textEmailAddress" IsRequired="true" ErrorMessage="Required!" runat="server" />
By default this control has EnableClientScript set to "true" for DHTML / client-side validation (as does the RequiredFieldValidator if I'm not mistaken). If you want to validate on the server you can simply type EnableClientScript="false". Since a required field validator is created I also added a property for ValidationGroup (which are a nice addition to 2.0).
<
asp:RequiredTextBox ID="textEmailAddress" IsRequired="true" ErrorMessage="Required!" ValidationGroup="signup" runat="server" />
Also if I make a field required but don't specify an ErrorMessage it defaults to "*". I can now cut the amount of code / typing down to:
<
asp:RequiredTextBox ID="textEmailAddress" IsRequired="true" runat="server" />
This took me about an hour to create and it was worth every second. Here is a limited functionality version posted on The Code Project that I used for a base.
HoverTextBox
The next control I thought to create was what I call a HoverTextBox. This is a very simple controls and is used to pretty-up a UI (if that's your thing!). I did contract work for a firm awhile back that was big on creating nice UI's. This control allows you to select an onMouseOver (focus())color as well as an onMouseOut (blur()) color. With this control you can give you end-user a visual representation of where they are on a large form.
<
asp:HoveTextBox ID="textAddress1" OnMouseOverColor="Aqua" OnMouseOutColor="White" Default="White" runat="server" />
Now you don't have to create CSS to get this effect. Oh, I forgot to mention that you can set a default color. So all textboxes will render to "Wheat" if that is the color you selected. Again, no more CSS (at least for this part of the textbox behavior!).

I plan on giving this away on my site in the near future as well possibly posting the source. I don't want to do that just yet because my "Control Library" only has these 2 two controls so far. Next I'm working on adding Phone Number (US), SSN, IP TextModes to the TextBox. These will include embedded javascript for on-the-fly formatting of text input / rendering.
If you're wondering how I got the asp prefix it's as easy as registering the "asp" prefix.
<%@ Register TagPrefix="asp" Namespace="ControlExtensionLibrary" Assembly="ControlExtensionLibrary" %>
Anyone else ever work on extending / creating controls?
Tags:
.NET,
C#
Apparently I spoke too soon last night when I said the installation went well. Well, it went well meaning it installed and I was still able to use Visual Studio 2005. That's always a good thing. This morning I go to create a "Linq to Sql" class and ReSharper informs me of about 10 errors (not to mention the 60+ redundant this.'s). I thought that maybe ReSharper (EAP 3.0.2) was a little buggy so I went into my code-behind and started to write some code.
SimpleSchedulerDataContext
db = new SimpleSchedulerDataContext()
That didn't give me any problems. Then I started to type a query. Keep in mind I am doing this while watching Scott Guthrie's video on creating a Linq to Sql class and performing basic queries. I start to type my query and hit a brickwall. The var keyword isn't even available to me. I have access to the cool namespaces of 3.5 but that is about it. I can type using System.Linq with no problems! I check the 'About' and see that .NET Framework 3.5 is in fact installed. I also check my 'Programs and Features' and there it is.
I did find a blog entry where Scott Guthrie mentions that they have seen problems when trying to install the .NET Framework 3.5 on Vista machines with the KB929916 installed. I just installed this and am going to reinstall the .NET Framework 3.5 on top of what was already supposed to have been installed.
Any suggestions or references would be greatly appreciated.
UPDATE #1
No luck! Check this out though (from DataContext class).
//---------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1378
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//---------------------------------------------------------------
I checked my project properties to see that the target Framework is 3.5. I'm at a loss as for where to start trying to figure this out.
UPDATE #2
Dammit! I really want to start using this. I posted on ASP.NET forums over an hour ago and haven't gotten any replies. I have searched Google and haven't found ANYTHING related to the problems I am having. I guess I'll e-mail Scott.
UPDATE #3
I did not e-mail Scott as I received an e-mail (comment notification) from David clueing me in on some horrible, horrible news. Apparently just because R# is available for C# 3.0 doesn't mean it is working for ALL of C# 3.0 (LINQ). That really sucks. I turned off code analysis for LINQ pages and I have my LINQ keywords. Niiiiice.

UPDATE #4
I still don't have Intellisense unless I use R#. Still Niiiiiice.
UPDATE #5
I figured out why Visual Studio doesn't have Intellisense. I imported the settings from Visual Studio 2005 where I had Visual Studio Intellisense replaced by R#. DOH!
Tags:
.NET,
Orcas,
Tools
I made a post a little while ago detailing the headaches I had trying to install Orcas CTP on my Vista machine (Home Premium). Since it isn't safe (yet) for me to run 2005 / 2008 on the same machine (Virtual PC) I will have to limit my C# 3.0 use to reading about the cool new features. I might have to upgrade to Vista Business Premium before I am even able to Debug in Visual Studio 2005 as there is NO workaround to allow this functionality. Anyway. C# 3.0. Take this Foo class below.
public
class Foo
{
private string _fooString;
private int _fooInt;
public string FooString
{
get { return _fooString; }
set { _fooString = value; }
}
public int FooInt
{
get { return _fooInt; }
set { _fooInt = value; }
}
public Foo()
{
}
}
Using C# 2.0 you would set the values of the properties like this:
Foo foo = new Foo();
foo.FooString = "string";
foo.FooInt = 1;
Simple enough. With a C# 3.0 it is a little more graceful:
Foo foo = new Foo { FooString = "string", FooInt = 1 };
Still simple enough. You could do something similar in C# 2.0 but this would involve overloading Foo's constructors.
public Foo(string fooString, int fooInt)
{
_fooString = fooString;
_fooInt = fooInt;
}
Foo foo = new Foo("string", 1);
While this is a similar approach, it does involve writing more code. Personally I don't mind writing overloads but the fact that I will not HAVE to will be nice.
Extension Methods
Extensions methods are going to be nice too. I first started reading about these a couple of months ago when looking up info on how to combine 2 Dictionary<K, V> into 1*. In C# 2.0 you have to derive from a type and override the methods. Not anymore.
public
static class FooExtensionMethods
{
public static string GetFooInformation(this Foo foo)
{
return string.Format("{0}, {2}", foo.FooString, foo.FooInt);
}
}
To use:
Foo foo = new Foo();
foo.FooString = "string";
foo.FooInt = 2;
Response.Write(foo.GetFooInformation);
*I can't find the link right now but I read a great article a couple of months ago about this guy creating a custom extension methods for Dictionary<K, V>. The method extension that stood was Dictionary.Combine. I will post it when I find it because I want to read it over again!
I am really looking forward to LINQ and will make posts about that in the coming days / weeks once I familiarize myself with it a little more.
Links
C# 3.0: An Introduction
LINQ: Granville Barnett
Tags:
.NET,
C#
This afternoon I decided to download and install Visual Web Developer "Orcas" Express Edition to at least start playing with some of the new features. After the quick download I ran the setup and then restarted, resumed, finished. Great. I open Orcas and start dinking around. At this time I get an e-mail from a friend asking for some code (ASP.NET 2.0) and I respond that I will get it to him soon. I open up Visual Studio 2005 and start writing the code that I will eventually send and when I press CTRL+F5 I am greeted with:

Umm. No. This code was JUST checked out of Subversion after being checked-in working 100% so there shouldn't be any build errors. I added a new "default.aspx" to an "Examples" directory and copy-and-pasted verbatim working code from said project and slightly altered. I am using ReSharper so most errors are highlighted even before pressing F5 / CTRL+F5.
So I click "No" and look at the code one more time. I DELETE the sample code knowing full well that now I am dealing with 100% working code. Again. Same as before with the damn build errors. This time I click "Yes" and am greeted with a page displaying an "HTTP 500 Internal Server Error." WTF?
In reading the output I see the following:
Error 1 Unable to initialize the native configuration support external to the web worker process (HRESULT=0x80004002). nativerd.dll must be in %windir%\system32\inetsrv.
Oooooooook. So I navigate to my windir\system32\inetsrv and check that nativerd.dll is in fact in this location. It is. I go to my inetpub and noticed that the default program for opening all of my 2.0 files are VWDExpress9.0. Really weird.
This is when I uninstall Orcas (had to do it twice) and .NET 3.5(pre-release). After the uninstallation I get a dialog box telling me that "Visual Studio 2005 may not work correctly after uninstalling Visual Web Developer Orcas Express Edition." Easy. I'll follow the directions step-by-step and fix this. After reading in detail the first 3 "possible" problems I did what the FAQ ultimately advised which was running Visual Studio 2005 repair. After this STILL NO LUCK!
Now I started to kind of freak out. What I did was uninstall all of the Windows Updates for today, restart, and prayed for the best.
That seemed to work. This thread makes mention that this might be a bug in Windows Vista OS. I posted a quick bullet list of how I went about resolving my issues in that IIS Forums thread.
I'm going to be lurking the Express Edition Forums over the next couple of days to see if this issue pops up over there.
Side Note:
TortoiseSVN rocks!
Tags:
.NET,
Orcas,
Tools
Andrew Robinson sent out an e-mail to our local .NET group about anonymous delegates. The e-mail got me interested and I started reading up on delegates in the 2.0 framework. I am currently working on a class for a project that uses a lot of Generic lists. While enumerating these lists I need to make changes to the collection and of course I am unable to make direct changes to the collection while I am enumerating (rightfully so!). The next logical thing to do is create a copy and make changes and after enumerating commit those changes to the collection. This entailed creating a method such as CopyList that would take a parameter of List<T> or simply an Object.
Two weeks ago I had a method that looked like the following.
static
List<Bar> CopyFoo(Foo item)
{
List<Bar> foo = new List<Bar>();
foreach (Bar bar in item.Bar)
foo.Add(bar);
return foo;
}
Pretty basic stuff. The method takes the Foo object and enumerates each Bar in item. Each Bar is added to another collection of Bar. Pretty simple and straight-forward. As simplistic as that looks, there is actually an easier, and in my opinion; more elegant way.
With the Generic List ForEach method you can dump the entire contents of a collection in one line!
static
List<Bar> CopyFoo(Foo item)
{
List<Bar> foo = new List<Bar>();
item.Bar.ForEach(delegate (Bar bar) {foo.Add(bar);});
return foo;
}
Very simple but a cool trick nonetheless. The action of the ForEach method is a delegate to a method that performs an action (List.Add) on the object (Bar) passed to it.
Tags:
.NET,
C#,
Interesting,
Programming
I`ve received the following error today while working on a method that INSERTS multiple records into a database. I am using the SqlCommand class and parameterized queries. Keep in mind this is a simple vanilla insert, hence the lack of a SQL stored procedure.
The variable name `@dayId` has already been declared. Variable names must be unique within a query batch or stored procedure.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: The variable name `@dayId` has already been declared. Variable names must be unique within a query batch or stored procedure.
The code below ( pseudo ) will give you the previous error.
private
void UpdateDatabase(int dayId, string bar)
{
using ( SqlConnection cn = connection )
using ( SqlCommand cm = new SqlCommand("INSERT @dayId, @bar", cn) )
{
cn.Open();
for ( int i = 0; i < 5; ++i )
{
cm.Parameters.AddWithValue("dayId", dayId + i);
cm.Parameters.AddWithValue("bar", bar);
cm.ExecuteNonQuery();
}
}
}
If you run into this same error when doing multiple inserts you simple need to clear your parameters after performing your ExecuteNonQuery().
private void UpdateDatabase(int dayId, string bar)
{
using ( SqlConnection cn = connection )
using ( SqlCommand cm = new SqlCommand("INSERT @dayId, @bar", cn) )
{
cn.Open();
for ( int i = 0; i < 5; ++i )
{
cm.Parameters.AddWithValue("dayId", dayId + i);
cm.Parameters.AddWithValue("bar", bar);
cm.ExecuteNonQuery();
cm.Parameters.Clear();
}
}
}
Easy. If I help only 1 person with this then I feel that I have done my job!
A little aside; I couldn't find any documentation for SqlCommand.Parameters.Clear() on MSDN. To me that seems strange.
Tags:
.NET,
C#,
Code,
Programming