Шерлок, вы столкнетесь с некоторыми проблемами, пытаясь использовать ModelBinder от MVC, поскольку они используют ControllerContext.
Я ответил на аналогичный вопрос ранее ChangeType, Convert - Преобразование из одного типа в другой , но это действительно то, что вы ищете.
Посмотри этот пост в моем блоге.
ChangeType - изменение типа переменной в C #
По сути, вы получаете единственный метод с именем ChangeType<T>
, который возвращает значение параметра, который вы ищете, строго типизированным способом, или значение по умолчанию, если параметр не существует.
Теперь, что касается пользовательских классов (в основном классов типов DTO), если вы не возражаете против использования отражения, у меня есть решение, которое также будет обрабатывать большинство пользовательских классов. Класс DtoBinder, упомянутый в конце завещания, будет хорошо работать.
По сути, последние 3 листинга кода содержат весь код, который вам понадобится для удовлетворения почти всех ваших потребностей в типичном сценарии веб-приложения. Кроме того, он расширяемый, поэтому, если вам нужно реализовать свой собственный механизм связывания, вы можете сделать это очень просто и зарегистрировать свой механизм связывания в RequestBinder из любой точки вашего приложения.
Так что, если вы не хотите использовать отражение для некоторых часто используемых объектов DTO, вы можете реализовать связыватель для типа и зарегистрировать его, и с этого момента он будет использовать ваше настраиваемое связующее. Во многом он похож на MVC ModelBinder по своей концепции.
Отредактировано -
Ниже приведен один файл .cs с кучей классов, которые я использовал в прошлом, чтобы делать именно то, что вам нужно. Первый MsPropertyAssignerProvider - это тот, с которым вы будете работать на своей странице.
Вы будете перебирать элементы управления и вызывать метод GetPropertyAssigner, передавая ему имя типа элемента управления. Этот метод возвращает экземпляр ObjectPropertyAssigner, который имеет один метод с именем SetPropertyValue, в который вы можете передать свой экземпляр объекта и экземпляр элемента управления.
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;
}
}
Сопутствующий класс указан ниже
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);
}
}
Извините, независимо от того, что я делаю, редактор полностью испортил листинг кода. Но я надеюсь, что это поможет.