我目前正在开发一些用户控件,以便我可以在项目中的多个位置使用它们。一个控件是关于编辑客户的地址列表。由于这需要在项目中的几个地方完成,我想让它成为一个简单的用户控件。用户控件包含转发器控件。默认情况下,转发器显示一个要编辑的地址项。如果需要添加更多地址,用户可以单击按钮以附加要输入的其他地址。用户控件应该用于创建新地址以及编辑现有地址。 地址业务实体看起来像这样:
public class Address
{
public string Street { get; set; }
public City City { get; set; }
public Address(string street, City city)
{
Check.NotNullOrEmpty(street);
Check.NotNull(city);
Street = street;
City = city;
}
}
正如您所看到的,只有街道和城市才能实例化地址。
现在我的想法是用户控件公开了一个名为Addresses
的集合属性。
此属性的getter从转发器收集地址并将其返回到集合中。 setter会将要编辑的地址数据绑定到转发器。
像这样:
public partial class AddressEditControl : System.Web.UI.UserControl
{
public IEnumerable<Address> Addresses
{
get
{
IList<Address> addresses = new List<Address>();
// collect items from repeater and create addresses
foreach (RepeaterItem item in addressRepeater.Items)
{
// collect values from repeater item
addresses.Add(new Address(street, city));
}
return addresses;
}
set
{
addressRepeater.DataSource = value;
addressRepeater.DataBind();
}
}
}
首先,我喜欢这种方法,因为它是面向对象的,因此很容易重用控件。但是在我的项目中的某个地方,我想使用此控件,以便用户可以输入一些地址。我想预先填写每个转发器项目的街道输入字段,因为我有这些数据,因此用户无需自己输入所有内容。
现在的问题是这个用户控件只接受处于有效状态的地址(因为地址对象只有一个构造函数)。所以我不能这样做:
IList<Addresses> addresses = new List<Address>();
addresses.Add(new Address("someStreet", null)); // i dont know the city yet (user has to find it out)
addressControl.Addresses = addresses;
所以上述情况是不可能的,因为我会从地址收到错误,因为该城市为空。
现在我的问题:我如何创建这样的控件? ;) 我正在考虑使用地址DTO而不是真实地址,因此以后可以将其映射到地址。这样我就可以传入和传出一个地址集合,其地址不需要有效。 或者我误解了用户控制的工作方式?有没有最好的做法?
答案 0 :(得分:3)
将Business Objects(具有严格规则和重新构造的构造函数)直接绑定到UserControls(可能必须允许处于部分和无效状态的数据)充满了危险。
如果您要使用地址视图模型(视图模型是用于在控制器和用户控件之间进行通信的DTO),那么您可以允许视图模型中的任何旧垃圾,这必须在之前进行验证它变成了一个地址。
这也允许将View / UserControl与业务层分离,因此重用变得更容易。