多年来我做了ASP.NET Web表单开发我被专有库所破坏,这让我可以做以下事情:
UpdateToObject(ControlsCollection, obj)
UpdateFromObject(ControlsCollection, obj)
概念上,代码做了一些与MVC Model Binder非常相似的东西,即将表单的发布值作为输入,它将填充自定义对象。基本上,它使开发人员免于执行猴子代码,例如
employee.Name = txtName.Text;
employee.DOB = DateTime.Parse(txtDOB.Text);
依旧......
现在,这个专有的库在我参与的新项目中不可用,而且它是一个Web表单项目。所以我想知道是否有一种方法可以在Web表单的上下文中使用System.Web.Mvc.DefaultModelBinder
。目标是从域对象和背面实现简单和容易的控制,最好考虑验证注释。
如果不可能,有人可能会指出我的开源解决方案来满足这种需求。我真的不想重写这样的代码。
提前致谢。
答案 0 :(得分:1)
Sherlock,你会遇到一些试图使用MVC中的ModelBinder的问题,因为它们依赖于ControllerContext。
我之前回答了类似的问题ChangeType, Convert - Converting from one type to another,但它确实是你正在寻找的。 p>
在我的博客上查看此博文 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);
}
}
抱歉,无论我做什么,编辑器都会彻底搞砸代码清单。但我希望这会有所帮助。
答案 1 :(得分:1)
你不能使用AutoMapper这样的东西吗?只需设置地图,它就会创建新对象并将值复制到其中。
答案 2 :(得分:0)