Sherlock, vous rencontrerez quelques problèmes en essayant d'utiliser le ModelBinder de MVC puisqu'ils s'appuient sur un ControllerContext.
J'ai répondu à une question similaire plus tôt ChangeType, Convert - Converting from one type to another mais c'est vraiment ce que vous cherchez.
Vérifiez ce post de blog sur mon blog ChangeType – Changing the type of a variable in C#
Essentiellement, vous obtenez une seule méthode appelée ChangeType<T>
qui retourne la valeur du paramètre que vous recherchez de façon fortement typé ou une valeur par défaut si la le paramètre n'existe pas.
Maintenant, en ce qui concerne les classes personnalisées (principalement les classes de type DTO), si cela ne vous dérange pas d'utiliser la réflexion, j'ai une solution qui gérera également la plupart des classes personnalisées. La classe DtoBinder mentionnée vers la fin du travail de volonté bien. Essentiellement, les 3 dernières listes de codes contiennent tout le code dont vous aurez besoin pour gérer presque tous les besoins que vous avez dans un scénario d'application Web classique. De plus, il est extensible, donc si vous avez besoin d'implémenter votre propre classeur, vous pouvez le faire très simplement et enregistrer votre classeur avec RequestBinder à partir de n'importe où dans votre application. Par conséquent, si vous ne voulez pas utiliser la réflexion pour certains objets DTO fréquemment utilisés, vous pouvez implémenter un classeur pour le type et l'enregistrer et à partir de ce point, il utilisera votre classeur personnalisé. À bien des égards, il est similaire au MVC ModelBinder dans son concept.
Edité -
Ci-dessous un fichier .cs avec un tas de classes que je l'ai utilisé dans le passé pour faire exactement ce dont vous avez besoin. Le premier MsPropertyAssignerProvider est celui avec lequel vous travaillez depuis votre page.
Vous pouvez itérer sur vos contrôles et appeler la méthode GetPropertyAssigner en lui passant le nom de type du contrôle. Cette méthode renvoie une instance d'un ObjectPropertyAssigner qui possède une méthode appelée SetPropertyValue que vous pouvez transmettre à votre instance d'objet et à l'instance de contrôle.
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;
}
}
La classe d'accompagnement sont énumérés ci-dessous
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);
}
}
Désolé, peu importe ce que je fais l'éditeur salit complètement la liste de code. Mais j'espère que cela aide.
Seuls les 1er et dernier paragraphes sont quelque peu pertinents à la question posée. Cela ne me dérange pas d'utiliser la réflexion. C'est ainsi que la bibliothèque propriétaire a fonctionné. – Sherlock
Je suppose que dans votre cas, parce que vous travaillez avec des contrôles, la solution est un peu plus impliquée. La classe DtoBinder peut créer une instance de votre objet Dto et affecter toutes les valeurs de propriété à une collection de NameValues. Donc, ce que vous devez faire est d'assembler cette collection à partir des noms et des valeurs du contrôle et de le remettre à DtoBinder. –
Juste modifié ma réponse originale avec quelques classes supplémentaires que j'ai utilisées dans le passé. –