0

我对课程和 OOP 完全陌生,所以请多多包涵。

我正在创建一个大型网络应用程序,我试图通过创建自己的类来保持整洁。

例如,我有一个Public Class Product有几个属性的。我使用它的一种方法是在页面加载时将产品 ID 分配给 ID 属性,该 ID 属性进而获取该产品的详细信息并将各种数据分配给其他属性。因此,在我的代码中,我可以使用例如 product.price 或 product.description 并获得适当的值。这工作得很好,但我发现因为该类是在页面加载时启动的,所以每次刷新页面时它都会从数据库中获取数据。我通过使用 anIf Not IsPostback来启动课程来停止这一点。这意味着数据仅在初始页面加载时被提取。到目前为止,一切都很好。

然后我需要将文本框中的值与产品的属性进行比较。我有一个 textchanged 事件

If textbox1.Text <> product.description Then....

但在这里我得到一条波浪线product.description,VS2010 说该对象未定义。它在 page.load 中变暗,因此我将 Dim 语句移到页面类之外,以便页面上的所有事件都可以访问它。

暗淡的声明是Dim product as New product

例如,在我的 not ispostback 代码块中product.ID = 1,它将获取产品 1 的所有产品属性

波浪线已经消失,但是当我运行页面时,页面加载时一切正常。显示数据,因此我的产品类工作正常。一旦我在 textbox1 中进行更改并且事件触发product.description什么都没有。它重新启动了。

我该如何阻止这种情况发生...

4

3 回答 3

1

您的“产品”不会在回发之间保留。

只有 aspx 页面中的控件对象会自动持久化/恢复。

为了解决这个问题,有多种方法。

如果产品是通过设置“Product.id = 1”加载的,那么我要做的是有一个隐藏字段,它在预渲染事件期间接收 product.id 的值(将其保存在页面中)并且在初始化事件中我会恢复“Product.id=hiddenfield.value”,但仅当它是重新加载对象的回发时。

编辑

感谢您选择我的答案。我将详细说明处理此问题的各种方法以及我提出答案的原因。

将密钥存储在 HiddenField 从 DB 重新加载

优点:产品始终是新鲜/正确/当前值。对应数据库。数据库在返回基于主键的记录方面非常有效。很少有数据发送到客户端浏览器并从客户端浏览器发回。低复杂度。客户端打开的每个页面都是安全隔离的。

缺点:多个数据库事务。如果数据库已经紧张或非常庞大,您可能需要考虑即使是最小的效率增益,但这在基于主键的记录中并不常见或不太可能

会话状态(存储整个对象)

优点:“加载”对象的最短时间,因为一旦加载它就可以在内存中使用。更少的数据库事务。没有数据捎带回客户端并再次返回。

缺点:如果在数据库中更改,对象可能会“过时”。如果两个用户都需要不同的“产品”,打开应用程序的多个页面的用户最终可能会得到错误的对象,因此为了完全安全,您需要一个更复杂的结构来存储一个以上的产品或基于某些产品来存储它们类型的密钥(例如产品 ID)。使用服务器内存,如果为成千上万的用户提供服务或您的产品数据很大,这可能会成为一个问题,特别是如果您在包含许多对象的许多页面中执行此操作。

序列化(将页面中的整个对象存储在一个字段中,类似于事件状态)

优点:一旦加载,特定产品的数据库仅被访问一次,然后该产品被保存在页面内,它是由服务器从字段中的数据或通过视图状态重新创建的。客户端打开的每个页面都是安全隔离的。在页面的 ViewState 中实现存储相当容易。

缺点:如果在数据库中更改,对象可能会“过时”。ALLOT 更多数据被添加到您的页面响应和用户的下一页请求中。实现起来更复杂,因为需要将对象设计为正确序列化。复杂对象需要分配手动代码才能成功序列化。

同样,还有许多其他方法可以解决这个问题,例如将项目存储在应用程序全局的同步字典样式对象中,但随着您的使用,它会变得越来越复杂。

于 2013-05-09T19:08:21.803 回答
1

这可能是标准的ASP.NET 页面生命周期问题。

初始化页面后,它会被发送到用户的浏览器。当用户点击某物时,浏览器会向您的应用程序发送回发请求。视图状态允许 textbox1 对象记住其 Text 属性中的内容。但是,您的 Page_Load 从头开始​​运行,是的,包括您的产品对象在内的所有内容都是从头开始重新创建的。

如果您希望您的产品对象在回发之前“记住”它所知道的内容,则必须提醒它。一种方法是将初始化值存储在Session state中,然后在 Page_Load 方法的回发部分刷新您的产品对象。

于 2013-05-09T19:19:10.647 回答
1

每次进行回发时,您都在使用页面类的新实例。您的课程的先前副本已被丢弃,并且可能在您的浏览器甚至将页面呈现到屏幕之前就已处置。

如果您想在 http 请求中保留一个值(其中回发只是一种类型),那么您需要将它放在 Session 之类的地方。

于 2013-05-09T19:26:36.467 回答