Another “Why didn’t someone tell me this earlier” Post

90% of the projects I work on need to send emails, and most clients don’t allow developer SMTP servers floating around their network (for good reason). So a big headache ensues trying to get access to an Exchange or SMTP server somewhere. I have been doing this same dance for years. But today I find a blog post about sending emails without an SMTP server. The .Net calls to SMTP just write the emails out on the file system. It’s just configuration even. So much to know, so little time.

Posted: Wednesday, July 29, 2009 7:12:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | .Net 3.5 | ASP.NET

Casting a Null

Found an interesting tidbit today. There is an ASP.NET page that is using session variables. The user has visited the page, and populated the session. But then the user lingers, and the session times out on a page that is not protected. The user then clicks a button, and the following line of C# code executes:

User foo = (User)Session[“bar”];

So what should happen here? An Exception? That’s what I would have thought. But not true. Since the session has expired, the session variable is now null, and you can cast a null into another data type having a value of null. Just as long as that type is nullable. So the line above is the same as:

User foo = (User)null;

which is perfectly valid.

I got the null reference exception down the line when trying to access a property of foo. So once again, defensive programming is the rule. Check your session variables for null!

Posted: Thursday, July 16, 2009 9:14:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | .Net 3.5 | Strange Problems

Don’t Do This

In ASP.NET, the DataList control renders as a table. Opening a new table in the header and trying to get rows to render just won’t end well. Lots of strange browser behavior should be the tip off that this isn't right.

Posted: Sunday, March 22, 2009 7:48:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | .Net 3.5 | ASP.NET

eBooks on CodePlex

Wriju has a gread roundup of eBooks/guidance available on CodePlex.

Posted: Friday, January 09, 2009 4:01:49 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | .Net 3.0 | .Net 3.5 | Programming | TFS | WCF

Quick ADO.Net Tip

If you need to stop a datareader in the middle, instead of at the end, you have to call cancel on the command object. Calling the Close() method will result in a timeout exception.

using (SqlCommand cmd = new SqlCommand(sql, conn))
{
          XmlReader reader = cmd.ExecuteXmlReader();
          reader.Read();

while (!reader.EOF)
{
            if (this.Cancel)
            {
                cmd.Cancel();
                reader.Close():
                break;
            }
            holder = reader.ReadOuterXml();
}
}
Posted: Monday, November 10, 2008 4:47:04 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

DataSets and Calculated Columns

Ran into a performance issue in a .Net remoting situation. A Winforms app is calling an application server asking for data. A relatively large DataSet (>10,000 rows, <6 columns) being passed over the wire was causing a performance problem. The database and application servers processed it quickly. Examining the transfer with WireShark showed that the transfer wasn't so bad either. There was a flurry of data passed, and then a bunch of waiting on the client-side, with the client CPU usage around 50% the entire duration of the wait. Turns out there is a calculated column in one of the data tables. The column is not calculated on the application server-side, so as not to pass a bunch of data across the wire that would be unnecessary. The calc happens on the client. That was the source of the slowdown and CPU usage. In the end the solution to the problem was not using the calculated column, we found a different solution to fix the business problem. I suppose you could perform the calculation in the SQL statement that was ultimately filling the DataSet. That might take longer to transfer, but won't slow down the client app.

Posted: Wednesday, June 11, 2008 4:06:26 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | Performance | Tools | Winforms

ASP.NET Web Project Build Events

I have a web project (the original 2005 web project type, not a web application project) and had a problem getting files copied to the bin directory. Essentially, one of the library projects referenced by the web project has an XML file in the project output, but when the solution is built, the XML file in the bin directory of the library project is not pulled into to the bin directory of the web project. Of course, a post-build event seemed like the thing to do, but web projects don't have support for that.

A little digging and I found this post by Scott Guthrie that describes a "Build Helper Project". You simply add an empty class library project to your solution. You then use the build events in the empty project use to add build events to your web project. You just make sure the project build order is correct so the events get called when you need them.

Posted: Monday, October 08, 2007 4:28:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | ASP.NET

Casting Text Data to Members in a Business Object via Reflection

I have a pipe-delimited text file that I am parsing and using to fill a collection of custom business objects. Instead of hard-coding the bits of each pipe-delimited line, I am using an XML file to map data items in the file to object members, like this XML fragment:

<Field>
    <Name>NAMID</Name>
    <Location>0</Location>
    <MapsTo>MemberId</MapsTo>
    <IsRole>false</IsRole>
</Field>

After parsing and matching the data element to the proper member name, I call this function:

public void SetDataMemberValue(string memberName, Member member, string data)
{    // get an instance      
     // of that object's type.
     Type objectType = member.GetType();
     PropertyInfo[] properties = objectType.GetProperties();
     foreach (PropertyInfo property in properties)
    {         if (string.Equals(property.Name, memberName, StringComparison.OrdinalIgnoreCase))
        {
            object[] args = new object[1];
            args[0] = data;
            object result = null;
 
            if (property.PropertyType == data.GetType())
            {
                //The type of the property matches the data's type
                result = data;
            }
            else
            {
               result = property.PropertyType.InvokeMember("Parse", BindingFlags.InvokeMethod, null, result, args);
            }
 
            if (result != null)
            {
                property.SetValue(member, result, null);
            }
        }
    }
}

The tricky bit is the InvokeMember call, which is casting my string to the appropriate type for the property. Of course this is they stylized version of the function, I removed the try-catch bits to make it smaller and readable for the acutal function. You should wrap the InvokeMember call with a try-catch as Parse methods can fail quite hard.

Posted: Monday, January 15, 2007 9:27:13 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

A BCL Method to Set a String in Title Case in C#

No need to create a function yourself or reference a VB library: A great post by Rick Strahl:

public static string TitleCase(string input)

{

      return System.Threading.Thread.CurrentThread.

             CurrentCulture.TextInfo.ToTitleCase(input);

}

Posted: Tuesday, May 23, 2006 12:11:44 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

Free Contract First Tool - WSCF

Thinktecture has released a Visual Studio 2005 compatible version of their free WSCF tool. WSCF is a Schema-Based Contract-First Web Services code generator. It allows you to design the messages, interfaces and data for contract-first style web services, acting as a replacement for XSD.exe and WSDL.exe. We have been using XSDObjectGen to do something similarly, but WSCF looks like it is much more flexible. For one thing, it generates collections using generics as List<T> instead of the non-type specific ArrayList that XSDObjectGen creates or the even more simplistic arrays that WSDL.exe creates. If you are using .Net 2.0, this is a great step forward for contract-first tools.
Posted: Friday, March 03, 2006 3:48:18 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

List Databinding Performance With DisplayMembers and ValueMembers

My copy of MSDN magazine arrived last night, and I read the article Practical Tips For Boosting The Performance Of Windows Forms Apps. Good read. Anyway, I was shocked to find out that I have been databinding lists improperly ever since I have been using .Net. I frequently wrote my code like this:

//Bad Code
combobox.DataSource = datatable;
combobox.DisplayMember = "State";
combobox.ValueMember = "Id";

//Good Code
combobox.DisplayMember = "State";
combobox.ValueMember = "Id";
combobox.DataSource = datatable;

Apparenly, order matters very much. In the first example, the combobox binds using the DisplayMember, then rebinds when updated with the ValueMember. In the second example, the binding only happens once.

In our current app, we have two lists that contain thousands of items that need to be bound, so we are binding them during the startup process so the user won't wait when requesting that data. The startup time was reduced by just under 40% by changing the order of the code for binding.

Posted: Wednesday, February 15, 2006 4:36:53 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | Performance | Winforms

ADO.Net 2.0 Presentation on January 20th

I will be giving a presentation at a Microsoft Developer Care event at their offices in Southfield, MI on January 20th. The event is sponsored by New Horizons and I will be talking about What's New in ADO.Net 2.0. There will be two other talks as well, see the agenda for details.
Posted: Sunday, January 29, 2006 6:26:58 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | Speaking

Generics and Enums or Enum.TryParse

I have a case where the user is entering strings into the application, and I have to match that string with the values from a given Enum. Normally that is not too difficult of a task, just convert the enum item to a string and compare, but in this instance I have a bunch of enums to do this with, so I didn't want to write a separate function for each enum type. So I figured generics might provide a solution and here is what I came up with, which is loosely based on the idea of int.TryParse:

/// <SUMMARY>
/// Takes a string that represents an enum member 
///   and returns the enum member
/// </SUMMARY>
/// <TYPEPARAM name="T">An Enum</TYPEPARAM>
/// <PARAM name="input">
///  The string that is the enum member name, case does 
///    not matter
/// </PARAM>
/// <PARAM name="returnValue">
/// The value from the enum that matches the string, or the 
/// first value of the enum /// </PARAM>
/// <RETURNS>
/// True when there is a match, false when not
/// </RETURNS>
/// <REMARKS>
/// - When no match the first item in the enum is returned
/// - The where clause attempts to constrain the input of T 
/// at compile time to be an Enum
/// </REMARKS> private bool GetEnumValue<T>(string input, out T returnValue)
where T : struct, IComparable, IFormattable, IConvertible { if(Enum.IsDefined(typeof(T), input)) { returnValue = (T)Enum.Parse(typeof(T), input, true); return true; } else //input not found in the Enum, fill the out parameter
// with the first item from the enum
{ string[] values = Enum.GetNames(typeof(T)); returnValue = (T)Enum.Parse(typeof(T), values[0], true); return false; } }
Posted: Wednesday, December 07, 2005 7:58:05 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

Comboboxes and Double-Clicks

The standard combobox control doesn't support the double-click event, as it is actually a combination of more than one control itself. In my case, I am using the combobox in simple mode with a textbox at the top and a permanently open list directly below the textbox. I needed for the listbox below to respond to the user double-clicking a list item. I found a great solution in a Usenet post by Jacques Bourgeois in microsoft.public.dotnet.framework.windowsforms.controls. Essentially the code simulates a double-click using the single-click event and a timer control.

Declare a timer control in your class, and in the load event of the form instantiate the timer set the interval of the timer to the interval of the double-click as set in the user's system:

this.comboDoubleClick = newTimer();

this.comboDoubleClick.Interval = SystemInformation.DoubleClickTime;

In the event handler for the timer, set the code to stop the timer:

this.comboDoubleClick.Enabled = false;

Add code to the single-click event handler to handle the double-click. When the event handler fires, if the timer is not enabled, start the timer (the first click). If the timer is enabled, a previous click has occurred within the system set interval for a double-click. This must be the second click of the double-click, so do whatever you needed the double-click to do and then disable the timer for the next single-click event.

private void Combo_MouseClick(object sender, MouseEventArgs e)
{
   
if (this.comboDoubleClick.Enabled == true)
    {
       
//Do double-click work here
       
this.comboDoubleClick.Enabled = false;
    }
   
else
   
{
       
this.comboDoubleClick.Start();
    }
}

Posted: Thursday, November 10, 2005 6:01:28 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | Winforms

Whidbey Beta 1 to Beta 2 Migration with Typed Datasets

Today we are migrating my project from Whidbey Beta1 to Beta 2 (if you know why this is happening today, go ahead and laugh with us), and our biggest hurdle so far is Typed Datasets.

We used dozens of XSD schemas to create typed datasets. Of course, Beta 2 no longer gives a menu option for creating a typed dataset directly from a schema (see this post in the Fedback Center for Visual Studio). The prospect of converting to the Dataset type of schema was daunting, and moving to the command line for xsd.exe was not going over so well either.

We did discover, however, that you can still generate the dataset using the IDE. In the properties of the XSD file, you can set the custom tool to MSDataSetGenerator. Then you can right-click the XSD file and choose Run Custom Tool. The IDE generates the code for the dataset. Whew!

Posted: Friday, July 01, 2005 4:25:55 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

Select Distinct in a DataTable (The Whidbey Version)

In my last post I described a “Select Distinct“ function for a datatable. This is a whole lot easier using Whidbey. You can get a distinct table based on a column in the DefaultView of the datatable:

DataTable d = dataSetName.dataTableName.DefaultView.ToTable(true, new string[] { "ColumnName" });

Posted: Wednesday, May 25, 2005 7:06:56 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | ADO.Net

Getting Started with the User Interface Application Block

There is an excellent “Hello World” article  for getting started with the UIAB at CodeProject by Roy Clemmons. If you have checked the docs that come with the block, you can appreciate a simplistic example. The block is a powerful piece of code, but you have to get started before harnessing the monster. I had a very difficult time distilling the example code from the block down to something simple that worked. The article from CodeProject did the trick.
Posted: Tuesday, April 12, 2005 4:51:36 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0

Data Access Application Block v2 Bug

Mark Brown posted his fix for a bug in the FillDataSet method of the SqlHelper in the Data Access Application Block. The problem occurs when trying to use the FillDataSet method to fill a typed dataset that contains more than two tables. It works great for the first two, not at all for the subsequent tables.

I gave Marks\'s fix a try, but it still didn't fix the problem for me. I did more digging and found a slightly different fix straight from the authors of the DAAB on the GotDotNet workspace for the DAAB. The fix is in the bug section (direct links don't seem to work) This cleared up my problem right away. Of course, the bug is fixed in version 3+ of the DAAB. If you are like me, the MSDN site has been my source for the code for the application blocks, and of course there is only 2.0 on the site.

I did not realize they were on version 3 of the DAAB. The authors have added support for an abastract factory to make the SqlHelper ADO.Net provider independant. I don't know about the rest of you, but the only projects I have ever had to change the database provider on have been Access upgrades. I have never had to move a database back end, say from SqlServer to Oracle. Is it more common than I realize?

Posted: Thursday, January 27, 2005 4:28:15 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 2.0 | ADO.Net