【问题标题】:Model-View-Presenter in ASP.NET with ListView and Repeater带有 ListView 和 Repeater 的 ASP.NET 中的 Model-View-Presenter
【发布时间】:2009-11-07 04:43:51
【问题描述】:

我一直在使用 ASP.NET 探索 MVP 模式,但在页面上使用数据绑定控件时,我无法将所有演示逻辑保留在演示器中。

以下场景和类只是示例,我正在处理的真实案例更为复杂。任何想法或方向将不胜感激。

假设我有一个页面显示有关客户的信息,包括姓名和地址。它还使用Repeater 控件呈现订单列表。

public class CustomerDto {
    public string Name { get; set; }
    public string Address { get; set; }
    public List<OrderDto> OrderList { get; set; }
}

public class OrderDto {
    public int Id { get; set; }
    public decimal Amount { get; set; }
    public bool IsRush { get; set; }
}

起初我让演示者在视图上设置名称、地址和OrdrerList。此时,Repeater 的 ItemDataBound 事件中仍然存在一些表示逻辑,具体取决于订单上 IsRush 的值。在我看来,这个逻辑不属于代码隐藏,而是属于可测试的演示者类。

public interface IOrderView {
    void SetName(string name);
    void SetAddress(string address);
    void SetOrderList(List<OrderDto> orderList);
}

public partial class OrderPage : Page, IOrderView
{
    public void SetName(string name) {
        labelName.Text = name;
    }

    public void SetAddress(string address) {
        labelAddress.Text = address;
    }

    public void SetOrderList(List<OrderDto> orderList) {
        repeaterOrders.DataSource = orderList;
        repeaterOrders.DataBind();
    }

    protected void repeaterOrders_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
            OrderDto orderDto = e.Item.DataItem as OrderDto;
            if (orderDto.IsRush) {
                Label labelOrderId = (Label)e.Item.FindControl("labelOrderId");
                labelOrderId.ForeColor = System.Drawing.Color.Red;
            }
        }
    }
}

似乎转发器中的每个项目都需要自己的 Presenter 和 View,但我在任何地方都没有找到任何类似的示例。我想出了几种方法来将所有演示逻辑保留在演示器中,但它们都感觉像是一个 hack,我想知道希望人们普遍处理这种情况。

谢谢!

【问题讨论】:

  • 为什么选择这种方法而不是 ASP.NET MVC?
  • 我更愿意使用 Model 2/MVC 应用程序,但我正在现有应用程序中创建新页面。谢谢。

标签: c# asp.net mvp


【解决方案1】:

答案肯定是在模糊的边界上。更改紧急订单标签的颜色绝对是在视图范围内,但确定紧急订单与普通订单的逻辑不是 IMO。

在你的情况下,我想象的是一个访客。对于转发器中的每个订单,您将该订单传递给演示者或控制器,然后根据视图不需要的领域知识调用视图中的适当方法。

OrderDto orderDto = e.Item.DataItem as OrderDto; controller.Visit(this, orderDto);

// 在你的控制器/演示器中的某个地方

无效访问(ISomeView 视图,OrderDto dto){ 如果(dto.IsRush){ view.RenderRushOrder(dto); } 别的 { view.RenderNornamlOrder(dto); } }

然后可以按照您已经详细说明的方式渲染视图。 IMO 它很好地分离了职责和我在非 MVC ASP.Net 实践中经常使用的东西

希望这会有所帮助。

【讨论】:

  • 我认为 Visit 不需要接受视图,因为 webforms 中的演示者通常都会引用视图。
【解决方案2】:

是否应用前景色的决定是合乎逻辑的,必须在演示者中进行测试。

您可以将 CssClass 或 ForeColor 属性添加到您的对象 DTO。您肯定希望能够根据您当前在 OnItemDataBound 中的逻辑来测试该属性是否已设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多