Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ASP.NET webforms中的模型绑定器_Asp.net_Webforms_Modelbinders_Defaultmodelbinder - Fatal编程技术网

ASP.NET webforms中的模型绑定器

ASP.NET webforms中的模型绑定器,asp.net,webforms,modelbinders,defaultmodelbinder,Asp.net,Webforms,Modelbinders,Defaultmodelbinder,多年来,我从事ASP.NET web表单开发,但我被一个专有库宠坏了,它允许我做以下事情: UpdateToObject(ControlsCollection, obj) UpdateFromObject(ControlsCollection, obj) 从概念上讲,代码做了一些与MVC Model Binder非常相似的事情,即给定表单的发布值作为输入,它将填充自定义对象。基本上,它将开发人员从诸如 employee.Name = txtName.Text; employee

多年来,我从事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
。目标是实现从域对象到域对象的简单而容易的控件填充,最好考虑验证注释。 如果这是不可能的,有人可以告诉我一个开源的解决方案来满足这个需求。我真的不想重写这样的代码


提前感谢。

Sherlock,您在尝试使用MVC中的ModelBinder时会遇到一些问题,因为它们依赖于ControllerContext

早些时候我回答了一个类似的问题,但这确实是你想要的

在我的博客上查看这篇博文

本质上,您会得到一个名为
ChangeType
的方法,该方法以强类型方式返回要查找的参数值,如果参数不存在,则返回默认值

现在,关于自定义类(主要是DTO类型类),如果您不介意使用反射,那么我有一个解决方案,可以处理大多数自定义类。在作业结束时提到的DtoBinder类将很好地解决这个问题

本质上,最后3个代码清单包含了处理典型Web应用程序场景中几乎所有需求所需的所有代码。此外,它是可扩展的,所以如果您需要实现自己的绑定器,您可以非常简单地实现,并从应用程序中的任何位置向RequestBinder注册您的绑定器

因此,如果您不想对某些常用的DTO对象使用反射,您可以为该类型实现一个绑定器并注册它,从那时起,它将使用您的自定义绑定器。在许多方面,它在概念上与MVC ModelBinder相似

编辑-

下面是一个.cs文件,其中包含一组类,我在过去使用过这些类来完全满足您的需要。第一个msPropertyAsignerProvider就是您在页面中使用的

您需要迭代控件,并调用GetPropertyAssigner方法,将控件的类型名传递给它。此方法返回ObjectPropertySigner的实例,该实例具有一个名为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);
    }
  }

抱歉,不管我做什么,编辑器都会把代码列表搞得一团糟。但我希望这能有所帮助。

你能用AutoMapper做这样的事情吗?只需设置地图,它就会创建新对象并将值复制到这些对象中。

这是一个很老的问题,但我在尝试了解默认模型绑定器的实际工作方式时遇到了这个问题

我有一个关于CodeProject的项目,它实际上做了你想要的(ed)


干杯

只有第一段和最后一段与提出的问题有点相关。我不介意使用反射。这就是专有库的工作原理。我想在您的案例中,因为您使用的是控件,所以解决方案更复杂一些。DtoBinder类可以创建Dto对象的实例,并为给定的NameValue集合分配所有属性值。因此,您需要做的是从控件的名称和值组装此集合,并将其交给DtoBinder。只需使用我过去使用的一些附加类编辑我的原始答案。