Solved

Reflection setValue to match my controls to my datacontext fields.

Posted on 2009-07-06
5
717 Views
Last Modified: 2013-11-05
I recently discovered reflection and realized how powerful it was to automate a lot of my mundane code writing.  For example I have a webform with over 300 fields.  I use a LINQ datacontext to manage the data, and instead of going through each control and say control = dataobject.field I thought I could use Reflection to match them together.

First I named my controls to have the same ID as my database fields, but I would put 'txt' or 'ddl' in front of them.  So my textbox would be 'txtFirstName' and my database field would be 'FirstName'.  When the page loads I would just say For each Control get the properties of my datacontext and match the ID's (removing the 'txt' from the beginning of the control name of course).  This works great.  Then I thought I could do the same thing with my updates and inserts, but I'm having a TON of problems with the setValue() method...

Looking at the code, I'm getting an error 'Object does not match target type'.  I'm not sure what I'm doing different.  Here's what I thought I would do:  pull all the properties for the datacontext object and loop through them matching them with the corresponding textbox (or control). See my code below.  I still get the error and I don't know why.

I've been trying to solve this for almost two days.
clientBenefitDataContext db = new clientBenefitDataContext();
 

        var contact = (from company in db.Contacts

                       from plan in

                           (

                               from p in db.PlanOptionsForContacts

                               where p.ContactID == company.ContactID

                               select p

                           ).DefaultIfEmpty()

                       from dental in

                           (

                               from d in db.DentalPlansForContacts

                               where d.ContactID == company.ContactID

                               select d

                           ).DefaultIfEmpty()

                       from vision in

                           (

                               from v in db.VisionPlansForContacts

                               where v.ContactID == company.ContactID

                               select v

                           ).DefaultIfEmpty()

                       where company.ContactID == Convert.ToInt32(cid)

                       select new { company, plan, dental, vision }).Single();
 
 

foreach (PropertyInfo field in contact.dental.GetType().GetProperties())

                {

                    

                    if (field.Name.ToString() == "id" || field.Name.ToString() == "ContactID")

                    {

                        continue;

                    }

                    else

                    {

                       

                        Type columnType = field.PropertyType.GetGenericArguments()[0];

                        if (columnType == typeof(DateTime))

                        {
 

                           TextBox txt = (TextBox)Globals.FindControlRecursive(ContactTabContainer, string.Format("txt{0}", field.Name.ToString()));

                                

                            field.SetValue(field.Name, rdp.Text, null);  // this is where the error is thrown

                            

                        }

                        //From here I want to set all the DataContext fields then do a db.SubmitChanges

                        

                    }

                    

                }

Open in new window

0
Comment
Question by:DrPcKen
  • 3
  • 2
5 Comments
 
LVL 1

Author Comment

by:DrPcKen
ID: 24791595

I think I just about got it using this code, but when I'm trying to get the type of the datacontext property (string, datetime, int32, etc...) it returns 'System.Runtime'.

DentalPlansForContact dp = new DentalPlansForContact();
                Type dbType = dp.GetType();

                foreach (PropertyInfo field in dbType.GetProperties())
                {

                    if (field.Name.ToString() == "id" || field.Name.ToString() == "ContactID")
                    {
                        continue;
                    }
                    else
                    {
                        Type columnType = field.Name.GetType(); //Trying to get TYPE here!
                        if (columnType == typeof(DateTime))
                        {

                            RadDatePicker rdp = (RadDatePicker)Globals.FindControlRecursive(ContactTabContainer, string.Format("txt{0}", field.Name.ToString()));

                            field.SetValue(dp, rdp.SelectedDate, null);
                            continue;

                        }
                        if (columnType == typeof(String))
                        {
                            TextBox txt = (TextBox)Globals.FindControlRecursive(ContactTabContainer, string.Format("txt{0}", field.Name.ToString()));

                            field.SetValue(dp, txt.Text, null);
                            continue;
                        }
                        if (columnType == typeof(Decimal))
                        {
                            TextBox txt = (TextBox)Globals.FindControlRecursive(ContactTabContainer, string.Format("txt{0}", field.Name.ToString()));

                            field.SetValue(dp, txt.Text, null);
                            continue;
                        }
                        if (columnType == typeof(Int32))
                        {
                            DropDownList ddl = (DropDownList)Globals.FindControlRecursive(ContactTabContainer, string.Format("ddl{0}", field.Name.ToString()));

                            field.SetValue(dp, Convert.ToInt32(ddl.SelectedValue), null);
                            continue;
                        }

                    }



                }
                db.SubmitChanges();
0
 

Accepted Solution

by:
Rudolf_Abel earned 500 total points
ID: 24791852
Type columnType = field.PropertyType.GetGenericArguments()[0];
if (columnType == typeof(DateTime))
{
                            TextBox txt = (TextBox)Globals.FindControlRecursive(ContactTabContainer, string.Format("txt{0}", field.Name.ToString()));
                               
                            field.SetValue(field.Name, rdp.Text, null);  // this is where the error is thrown
                         }

Type columnType = field.PropertyType.GetGenericArguments()[0];

if (columnType == typeof(DateTime)) \\this means field (or property) type should be DateTime...

{

                            TextBox txt = (TextBox)Globals.FindControlRecursive(ContactTabContainer, string.Format("txt{0}", field.Name.ToString()));

                                

                            field.SetValue(field.Name, rdp.Text, null);  

                            // AND here... you want to set String in DateTime property, also first parameter of SetValue must be parent object of property
 

                         }
 

try 

field.SetValue(contact.dental, DateTime.Parse(rdp.Text), null);

or
 

DateTime dt=DateTime.Now;

if(DateTime.TryParse(rdp.Text, out dt))

{

          field.SetValue(contact.dental, dt, null);

}

else

{

          //throw new Exception("Invalid date/time format");

}

Open in new window

0
 

Expert Comment

by:Rudolf_Abel
ID: 24791871
field.SetValue(contact.dental, DateTime.Parse(rdp.Text), null);

OR
 
DateTime dt=DateTime.Now;
if(DateTime.TryParse(rdp.Text, out dt))
{
          field.SetValue(contact.dental, dt, null);
}
else
{
          //throw new Exception("Invalid date/time format");
}
0
 
LVL 1

Author Comment

by:DrPcKen
ID: 24793555
Great! That looks like that is setting the datacontext value properly.  Now I'm running into a similar problem I had last night.

When it loops through my foreach block, it gets the field type of the datacontext object like this:

Type columnType = field.PropertyType.GetGenericArguments()[0];

This of course gets the data type of the column in the datacontext object.  Now on my form my first control is a textbox with a datetime, my second is an int32, and my third is a string.   The foreach loops through my datetime and int32 just fine but when it gets to a string datatype and tries to get the type, I get this error on the GetGenericArguments()[0] method:

Index was outside the bounds of the array.

Why is it having a problem getting the string datatype but everything else seems fine?

Thanks for your help!
0
 
LVL 1

Author Comment

by:DrPcKen
ID: 24798714
Ok the problem I'm having now is whenever I try to get the type of my object and it is a string, it errors out saying 'Index was outside the bounds of the array'.  All the other datatypes don't have this problem.  

This is how I'm getting the datatype:

Type columnType = field.PropertyType.GetGenericArguments()[0];
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
ASP.NET e-commerce website 4 30
Image(7) 1 37
dynamic menu in asp.net c# 11 30
Convert to Hour/minute textbox and compare 3 36
This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
In .NET 2.0, Microsoft introduced the Web Site.  This was the default way to create a web Project in Visual Studio 2005.  In Visual Studio 2008, the Web Application has been restored as the default web Project in Visual Studio/.NET 3.x The Web Si…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now