Sherlock, you will encounter some problems trying to use ModelBinder from MVC, as they rely on ControllerContext.
I answered a similar question before ChangeType, Convert - Converting from one type to another , but this is really what you are looking for.
Check out this blog post on your blog ChangeType - changing a variable type in C #
Essentially, you get a single method called ChangeType<T> that returns the value of the parameter you are looking for in a strongly typed way or the default value if the parameter does not exist.
Now, with regard to custom classes (mainly DTO class classes), if you don't mind using reflection, then I have a solution that will handle most custom classes. The DtoBinder class mentioned at the end of the work will be well executed.
In fact, the last 3 code lists contain all the code you need to handle almost all of your needs in a typical web application scenario. In addition, it is extensible, so if you need to implement your own binder, you can do it very simply and register your binder with RequestBinder from anywhere in your application.
So, if you do not want to use reflection for some commonly used DTO objects, you can implement a binder for the type and register it, and from now on, your custom binder will be used on it. In many ways, this is similar to the MVC ModelBinder in concept.
Edited -
Below is a single .cs file with a bunch of classes that I used in the past to do exactly what you need. The first MsPropertyAssignerProvider is the one with which you will work from your page.
You will iterate over the controls and call the GetPropertyAssigner method, passing it the name of the control type. This method returns an instance of ObjectPropertyAssigner, which has one SetPropertyValue method, which you can pass to the object instance and control instance.
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 is shown 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 messed up the code list. But I hope this helps.