Sherlock,你會遇到一些問題,試圖從MVC使用ModelBinder,因爲它們依賴於ControllerContext。
我以前回答過類似的問題ChangeType, Convert - Converting from one type to another但它確實是你在找什麼。
退房這篇博客我的博客上 ChangeType – Changing the type of a variable in C#
從本質上講,你會得到一個名爲ChangeType<T>
一個方法,返回你在一個強類型的方式尋找參數,或者如果缺省值的值參數不存在。
現在就自定義類(主要是DTO類型類)而言,如果您不介意使用反射,那麼我也有一個解決方案來處理大多數自定義類。 DtoBinder類很好地提到了意願工作的結尾。
本質上,最後3個代碼清單包含您需要的所有代碼,以便處理典型Web應用程序場景中幾乎所有的需求。另外它是可擴展的,所以如果你需要實現你自己的綁定,你可以很簡單地做到這一點,並從您的應用程序的任何位置註冊您的綁定與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);
}
}
對不起,不管我做什麼編輯器完全弄亂了代碼清單。但我希望這有助於。
只有第一段和最後一段與提出的問題有些相關。我不介意使用反射。這是專有圖書館的工作方式。 – Sherlock 2010-11-09 03:56:55
我想你的情況是因爲你正在使用控件,解決方案涉及更多一點。 DtoBinder類可以創建Dto對象的實例併爲給定的NameValues集合分配所有屬性值。所以你需要做的是從控件的名字和值中組合這個集合,並把它傳遞給DtoBinder。 – 2010-11-09 07:05:53
剛剛編輯了我原來的答案,並附加了我以前使用過的其他類。 – 2010-11-09 07:18:26