Шерлок, вы столкнетесь с некоторыми проблемами, пытаясь использовать 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);
}
}
Извините, что бы я ни делал, редактор полностью портит листинг кода. Но я надеюсь, что это поможет.
person
Shiv Kumar
schedule
08.11.2010