在ASP.NET中使用ListView和Repeater的Model-View-Presenter模式

3

我一直在研究ASP.NET中的MVP模式,但是当页面上使用数据绑定控件时,我很难将所有展示逻辑保留在Presenter中。

以下场景和类仅供参考,我正在处理的实际情况更加复杂。如果有任何想法或指导,将不胜感激。

假设我有一个页面,显示有关客户的信息,包括姓名和地址。它还使用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; }
}

一开始我让演示者在视图上设置名称、地址和订单列表。此时,在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,但我在任何地方都没有找到类似的例子。我想出了几种方法来将所有演示逻辑保留在Presenter中,但它们都感觉像是一个hack,我想知道人们通常如何处理这种情况。

谢谢!


你为什么选择这种方法而不是ASP.NET MVC? - Robert Harvey
我更喜欢使用Model 2/MVC应用程序,但我正在现有应用程序中创建新页面。谢谢。 - celticpride
2个回答

4
答案肯定在模糊的边界上。更改快速订单标签的颜色肯定属于视图范畴,但是确定快速订单与普通订单的逻辑不是我的意见。在您的情况下,我想象一下一个访客。对于重复器中的每个订单,您将该订单传递给主持人或控制器,然后根据视图不需要的领域知识调用视图中的适当方法。
OrderDto orderDto = e.Item.DataItem as OrderDto;
controller.Visit(this, orderDto);

// 在控制器/主持人的某个地方你有

void Visit(ISomeView view, OrderDto dto) {
   if (dto.IsRush) {
        view.RenderRushOrder(dto);
   } else {
        view.RenderNornamlOrder(dto);
   }
}

然后,视图可以呈现如您已经详细说明的那样。在我看来,它很好地分离了责任,并且是我在非MVC ASP.Net实践中经常使用的东西。

希望这可以帮助到您。


我认为Visit不需要接受视图,因为WebForms中的Presenter通常已经有对视图的引用了。 - epitka

1

是否应用ForeColor的决定是逻辑性的,必须在Presenter中进行以便进行测试。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接