Sherlock, you'll run into some issues trying to use the ModelBinder from MVC since they rely on a ControllerContext.
I answered a similar question earlier ChangeType, Convert - Converting from one type to another but it is really what you're looking for.
Check out this blog post on my blog
ChangeType – Changing the type of a variable in C#
Essentially, you get a single method called ChangeType<T>
that returns the value of the parameter you're looking for in a strongly typed fashion or a default value if the parameter does not exist.
Now as regards custom classes (DTO type classes mainly), if you don't mind using reflection then I have a solution that will handle most custom classes as well. The DtoBinder class mentioned towards the end of the will job nicely.
Essentially, the last 3 code listings contain all of the code you'll need in order to handle almost every need you have in a typical Web application scenario. Plus it's extensible, so if you need to implement your own binder you can do that very simply and register your binder with the RequestBinder from anywhere in your app.
So if you don't want to use reflection for certain frequently used DTO objects, you can implement a binder for the type and register it and from that point on it will use your custom binder. In many ways it's similar to the MVC ModelBinder in concept.
Edited -
Below is one .cs file with a bunch of classes that I've used in the past to do exactly what you need. The first one MsPropertyAssignerProvider is the one you'd be working with from within your page.
You'd iterate over your controls and call the GetPropertyAssigner method passing it the type name of the control. This method returns an instance of an ObjectPropertyAssigner that has one method called SetPropertyValue that you can pass your object instance and the control instance to.
internal class MsPropertyAssignerProvider
{
private Hashtable propertyAssigners;
internal MsPropertyAssignerProvider()
{
propertyAssigners = new Hashtable();
RegisterPropertyAssigner(typeof(TextBox).ToString(), new TextBoxValueExtractor());
RegisterPropertyAssigner(typeof(DropDownList).ToString(), new DropDownListValueExtractor());
RegisterPropertyAssigner(typeof(Label).ToString(), new LabelValueExtractor());
RegisterPropertyAssigner(typeof(CheckBox).ToString(), new CheckBoxValueExtractor());
}
internal void RegisterPropertyAssigner(string identifier, IMsObjectPropertyAssigner assigner)
{
if (propertyAssigners.ContainsKey(identifier))
throw new DuplicatePropertyAssignerRegistrationException(identifier);
propertyAssigners.Add(identifier, assigner);
}
internal IMsObjectPropertyAssigner GetPropertyAssigner(string identifier)
{
return (propertyAssigners.ContainsKey(identifier)) ? (IMsObjectPropertyAssigner)propertyAssigners[identifier] : null;
}
}
The accompanying class are listed below
public interface IMsObjectPropertyAssigner
{
void SetPropertyValue(object obj, System.Web.UI.Control control);
}
internal abstract class BaseValueExtractor : IMsObjectPropertyAssigner
{
protected MsReflectionHelper reflectionHelper = new MsReflectionHelper();
protected string FixStringForNumber(string stringValue)
{
if (stringValue.Length == 0)
return "0";
else
return stringValue;
}
public abstract void SetPropertyValue(object obj, System.Web.UI.Control control);
}
internal class TextBoxValueExtractor : BaseValueExtractor
{
public override void SetPropertyValue(object obj, System.Web.UI.Control control)
{
TextBox textBox = (TextBox)control;
PropertyInfo propInfo = reflectionHelper.GetPropertyInfo(obj, control.ID);
Type propType = propInfo.PropertyType;
if (propType == typeof(System.String))
reflectionHelper.SetPropertyValue(obj, control.ID, textBox.Text);
else if (propType == typeof(System.Int16))
reflectionHelper.SetPropertyValue(obj, control.ID, Int16.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency));
else if (propType == typeof(System.Int32))
reflectionHelper.SetPropertyValue(obj, control.ID, Int32.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency));
else if (propType == typeof(System.Int64))
reflectionHelper.SetPropertyValue(obj, control.ID, Int64.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency));
else if (propType == typeof(System.Double))
reflectionHelper.SetPropertyValue(obj, control.ID, Double.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency));
else if (propType == typeof(System.Single))
reflectionHelper.SetPropertyValue(obj, control.ID, Single.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency));
else
reflectionHelper.SetPropertyValue(obj, control.ID, textBox.Text);
}
}
internal class DropDownListValueExtractor : BaseValueExtractor
{
public override void SetPropertyValue(object obj, System.Web.UI.Control control)
{
DropDownList dropDownList = (DropDownList)control;
reflectionHelper.SetPropertyValue(obj, control.ID, dropDownList.SelectedValue);
}
}
internal class LabelValueExtractor : BaseValueExtractor
{
public override void SetPropertyValue(object obj, Control control)
{
Label label = (Label)control;
reflectionHelper.SetPropertyValue(obj, control.ID, label.Text);
}
}
internal class CheckBoxValueExtractor : BaseValueExtractor
{
public override void SetPropertyValue(object obj, Control control)
{
CheckBox checkbox = (CheckBox)control;
reflectionHelper.SetPropertyValue(obj, control.ID, checkbox.Checked);
}
}
Sorry no matter what I do the editor completely messes up the code listing. But I hope this helps.