Featured Post

Taco

Last night I was driving home and saw something run out in front of the truck.  Turns out it was a very young Chihuahua puppy. He ran up under the truck and I spent the next few minutes trying to coach him out with no luck.  Finally some neighbors that live down the street stopped to help.  But then...

Read More

How an open source developer transitioned to .Net

Posted by Keith Elder | Posted in .Net, Asp.Net, Open Source, PHP, Programming | Posted on 11-03-2006

0

For a long time I’ve been wanting to put this together.  A lot of my friends who were open source advocates like myself are perplexed with my transition to what they call the “Dark Side” of development.  Referring of course to Microsoft as the evil empire.  I took some time this morning to finish how and why I migrated from programming mainly in PHP to .Net.  I didn’t want to put this information into a blog post because as I was writing it, it just didn’t feel right so I created an article out of it.  In order to give you the full picture I give some information on my background to cement how firmly planted I was in open source technologies.  Then I give you some of my thoughts on the conversion process.  In the end, I give some advice for others that might be curious as how to make this conversion.  

Read the article “How An Open Source Developer Transitioned to .Net”

 

 

Converting Generic Lists or Collections to a DataSet

Posted by Keith Elder | Posted in .Net, Programming | Posted on 10-03-2006

24

Today I had a situation where I was calling a web service that returned an array of items.  Here is a sample of the XML the web service was returning. 

<?

xml version=1.0 encoding=utf-8?>
<
ItemCollection>
   <
item>
      <
FirstName>Keith</FirstName>
      <
LastName>Elder</LastName>
      
<FavoriteColor>Blue</FavoriteColor>
   </
item>
   <
item>
      <
FirstName>Chris</FirstName>
      <
LastName>Risner</LastName>
      
<FavoriteColor>Pink</FavoriteColor>
   </
item>
   <
item>
      <
FirstName>David</FirstName>
      <
LastName>Little</LastName>
      <
FavoriteColor>Carnation Pink</FavoriteColor>
   </
item>
</
ItemCollection>

The web service returned the data as expected but I needed to bind this to a DataGridView in the user interface.  For anyone that has used VS2005 you know this is pretty simple.  I added a new data source of type “Object” and selected my ItemCollection object that was generated from the WSDL of the web service.   I dropped the ItemCollection onto the designer and I had a DataGridView with all of my columns.  So far, I’ve spent about 30 seconds on this and I’ve connected to a web service and bound data to the UI.  I was going to be done with this in a few minutes.  I proceeded to take out the columns that I didn’t want showing and built the solution and everything looked great. 

I then referred back to the spec and noticed something that I missed.  The columns need to be sortable in the UI.  This poses a problem because the data that is coming back from the web service gets converted into an array of items (items[]).  Although we can bind an array to a DataGridView there isn’t an easy way to make the DataGridView sort this information based on each column.

I stared at my screen for a few minutes and came to the conclusion that I was going to need to convert the items[] to a DataSet since when bound to a DataGridView it would provide automatic sorting as well as filtering down the road in case someone decided they wanted to search this data (which they typically do). I started then writing a CollectionToDataSet object that would take a collection of items and convert the collection to a DataSet.  When you decide to go down this path to make this type of library you really hate building something that only works for one type of object.  I first got the new class working but it only worked with the type of object I was working with.  During my playing around with the new class a light bulb went off and it hit me this would be a good place to implement a Generic. 

Here is the end result of the class which uses a Generic to figure out which type of object is being passed in.  The only thing it must do is implement the ICollection interface and things work.  Here is what I came up with.

    /// <summary>

    /// This will take anything that implements the ICollection interface and convert

    /// it to a DataSet.

    /// </summary>

    /// <example>

    /// CollectiontoDataSet converter = new CollectionToDataSet<Letters[]>(letters);

    /// DataSet ds = converter.CreateDataSet();

    /// </example>

    /// <typeparam name=”T”></typeparam>

    public class CollectionToDataSet<T> where T : System.Collections.ICollection

    {

        T _collection;

        public CollectionToDataSet(T list)

        {

            _collection = list;

        }

 

        private PropertyInfo[] _propertyCollection = null;

        private PropertyInfo[] PropertyCollection

        {

            get

            {

                if (_propertyCollection == null)

                {

                    _propertyCollection = GetPropertyCollection();

                }

                return _propertyCollection;

            }

        }

 

        private PropertyInfo[] GetPropertyCollection()

        {

            if (_collection.Count > 0)

            {

                IEnumerator enumerator = _collection.GetEnumerator();

                enumerator.MoveNext();

                return enumerator.Current.GetType().GetProperties();

            }

            return null;

        }

 

        public DataSet CreateDataSet()

        {

            DataSet ds = new DataSet(“GridDataSet”);

            ds.Tables.Add(FillDataTable());

            return ds;

        }

 

        private DataTable FillDataTable()

        {

            IEnumerator enumerator = _collection.GetEnumerator();

            DataTable dt = CreateDataTable();

            while (enumerator.MoveNext())

            {

                dt.Rows.Add(FillDataRow(dt.NewRow(),enumerator.Current));

            }

            return dt;

        }

 

        private DataRow FillDataRow(DataRow dataRow, object p)

        {

            foreach (PropertyInfo property in PropertyCollection)

            {

                dataRow[property.Name.ToString()] = property.GetValue(p, null);

            }

            return dataRow;

        }

 

        private DataTable CreateDataTable()

        {

            DataTable dt = new DataTable(“GridDataTable”);

            foreach (PropertyInfo property in PropertyCollection)

            {

                dt.Columns.Add(property.Name.ToString());

            }

            return dt;

        }

    }

 

There you go!  A class to take any type of object that implements the ICollection interface and convert it to a DataSet.

 

As I was writing this article I thought of another way this could be done.  Since the items[] is serializable to XML and a DataSet can take XML and convert that to a DataSet through the ReadXml() method, what I could have done is convert the object to XML, then have a DataSet just read in the XML.  Just food for thought.  I may play with that later on to see which one is “faster”.  I can tell you that serializing the object and then converting it would be a lot less code to write initially, however, this class will probably come in handy more than not.

 

Let me know what you think about the class or if you have any ideas on how to improve it or ways you would have done it differently.  I’ve attached the class file to this post for those that want to download it and give it whirl.

Glad I dropped Tivo for Media Center

Posted by Keith Elder | Posted in Computer Hardware, Internet, Man Toys, PC Gaming, PC Software | Posted on 09-03-2006

0

It was December 2001 when my wife bought me a Tivo for Christmas (see tivo review). At the time I loved it. It was the best thing since electricity. I decided to not purchase the lifeline subscription because I knew something better was going to come out with more hard drive space, ethernet etc. As it turns out I was right. Back then I think it was soemthing like $9.95 per month. Not too bad really. I remember walking around the office after returning from Christmas break selling Tivo to everyone. One of my co-workers at the time, Mike Kimsal listened to how things worked and in true Mike fashion researched it to death and when he decided he wanted one, like a true geek he wanted it RIGHT THEN! It’s funny because he called me on Super Bowl Sunday during the game wondering where he could get a Tivo in Ann Arbor. Luckily I had Tivo so I could pause the game otherwise he would have been in big trouble. I kept the Tivo around and kept selling them to anyone that asked and that would listen. By now they were becoming main stream. Sorta like Google where you hear people say “google for it” you started hearing people say I “Tivoed” so and so show last night. Probably a year or so after we owned the Tivo they released a newer version which could get its listings via wireless download. We upgraded ours and continued to use Tivo. By this time the price had gone up to $12.95 a month though. Where am I going with this posting you ask? Well, earlier this week Tivo announced new pricing plans. They’ve gotten rid of the lifeline subscription and instead charge you $19.95 a month or $224 prepaid if you want to buy a year in advance. Thanks but no thanks Tivo! shuttle xpcI haven’t posted about it to the blog but I took my Shuttle PC I purchased back in 2003 and converted it to run Windows Media Center several months ago, Novemeber 2005 to be exact. The only thing I had to do to convert it to media center was purchase a Haupaugge MCE 500 tuner. It has two tuners on it which allow you to record two shows at once or watch one and record one. As a side note about MCE you could even add two MCE 500 cards and record 4 shows at once, how cool is that? So for about a $100.00 I took an existing PC and converted it to Media Center and don’t have to pay Tivo a DIME every month. You can do your own research about media center but its a very cool platform and there are tons of hacks and even a complete API to develop custom plugins for it. After several months MCE is still running and recording shows all for the low low price of $0.00 per month. Besides the fact you have a computer and can do WAY more with it than the Tivo I call it a win. Wake up Tivo, you are approaching having to be put into the budget with your pricing and there are cheaper ways to get the same thing.

Single quotes in DataView.RowFilter and DataSet Selects

Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 09-03-2006

1

I’ve been working on a new feature for a Smart Client at work and it was time to push it to beta and have QA go over it.  I was speaking to the QA team member and they were certain they could break the new feature with just a single quote.  The reason this QA team member said this is they test a lot of PHP web apps which are notoriuos for this type of mistake because of magic quotes turned on or off or whatever.  As I explained to them, the Smart Client shouldn’t encounter this when saving or deleting data as ADO.Net does a pretty good job of handling this type of thing.

Later in the evening I got an email from the QA team member with a screen shot where they had created an entry with a single quote in it. O’Connel for example.  At first I thought it was a joke and then I confirmed it by doing it myself.  What happened I wondered?  I’ve never seen this before.  So, I dug into the code. 

Smart Client HelpDesk Sample AppIn this particular application the screen it occured on was a screen where I had applied a DataView filter to narrow the results of a DataSet.  Here is a simple app I built called “Help Desk” to show you what I am talking about.  Below the menu in the sample you’ll notice I added a TextBox and a Filter button to the ToolStrip.  As you type information into the TextBox it filters the dataset by the First Name column.  Here is how that’s done.

private void toolStripTextBox1_TextChanged(object sender, EventArgs e)
{
   DataView dv = adventureWorksDataSet.Contact.DefaultView;
   dv.RowFilter = “FirstName LIKE ‘%”+ toolStripTextBox1.Text + “%’”;
   this.contactBindingSource.DataSource = dv;
}

The problem the QA team member found was not in the datalayer.  It is pretty simple to see that if you have a single quote in the toolStripTextBox1 object it is going to break the syntax of the RowFilter.  So that’s the problem, now let’s fix it.  I solved it quickly by doing this:

private void toolStripTextBox1_TextChanged(object sender, EventArgs e)
{
   DataView dv = adventureWorksDataSet.Contact.DefaultView;
   dv.RowFilter = “FirstName LIKE ‘%”+ toolStripTextBox1.Text.Replace(“‘”, “””) + “%’”;
   this.contactBindingSource.DataSource = dv;
}

This got me to thinking though, what other situations would this come up.  There may be others where you need to be careful to watch out for this but the only other similar situation was whereby you would do a select on a DataTable to return an array of rows.  For example:

AdventureWorksDataSet

.ContactRow[] rows = adventureWorksDataSet.Contact.Select(“FirstName=’” + toolStripTextBox1.Text.Replace(“‘”, “””) + “‘”);

I then started testing all types of other characters in this situation and the single quote is the only thing I came up with that would break it.  I guess in the end we were both right.  I was right in the fact that the datalayer wouldn’t be broken but the QA team memeber did in fact find break it with a single quote.  Note to self.  Self, if you are doing a RowFilter or DataSet Selects with a filter and are getting the input from the user, replace the single quotes.

I’ve attached the sample Help Desk solution to this post for those that want to download and play with it.  All you need is the AdventureWorks database and change the connection string to your own connection string.