存储Web自定义控件数据的位置在哪里?

3

我正在创建一个扩展WebControl的自定义控件。这个Web控件允许消费者在标记中定义一组列,就像这样:

<Custom:CustomGrid>
<Columns>
    <Custom:DataColumn HeaderText="FirstName" />
    <Custom:DataColumn HeaderText="LastName" />
</Columns>

将一个IEnumerable放入DataSource属性中,然后将其呈现为表格。此控件还允许分页。DataSource中的IEnumerable是完整列表,我每次显示列表的一页。我已经将当前页面、每页行数等保存到视图状态中。我应该将完整列表也放入视图状态中吗?也许是会话(session)?这个列表可能会变得有点庞大。也许用随机键在会话中保存,然后将键保存在视图状态中?

编辑: 我认为强制要求IEnumerable中的所有类型都可序列化是不正确的。这样公平吗?那我需要将数据源复制到其他数据结构中以进行序列化吗?

编辑2: 即使我使用基类控件而不是实现RenderChildControls,我仍然需要实现CreateChildControls,但我仍然需要在某个地方保留数据,或者我错过了基类的重点?

2个回答

2

的确,并不是所有的IEnumerable实例都可以序列化。

如果查询运行成本较低,我不会持久化整个数据集,而只是为不同的页面或排序方式再次运行查询。

如果将数据放在视图状态中,你的页面会变得非常大。如果用户数量很多且数据集很大,则会导致Session状态无法扩展。如果我将一百万行绑定到你的控件上呢?或者如果你的控件在重复器中使用并在页面上显示了100次呢?

你确定需要持久化数据吗?这不是过早地优化了吗?

请记住,你的控件是一个UI组件。视图状态应该包含足够的信息来维护其UI状态。状态的更改(例如:切换到不同的结果页)是你的控件应该将责任传递给数据源的内容。

看看经典的GridView控件。它显示你所提供的并记住它。如果你正在使用分页,则会引发事件以说明“用户已更改页面;给我第x页的数据”。对我来说,这是UI控件的最佳实践。


这大概就是我最终所做的。由于数据集不是很大,因此我只是将设置DataSource属性的责任在每次postback时传递给消费页面,并且我仅在ViewState中存储需要将DataSource恢复到先前状态所需的内容。 - Elad Lachmi

0

为实现数据绑定控件,最好使用专门设计用于执行此任务的基类。例如,在ASP.NET中存在CompositeDataboundControl,可以用作实现自定义数据绑定控件的基类。我建议查看以下Dino Esposito文章:http://msdn.microsoft.com/en-us/library/aa479016.aspx

基本上,如果您创建像ASP.NET GridView这样的控件,则会在ViewState中存储值。更明确地说,它会创建许多DataRow控件,这些控件保存了分配的值。在postback期间,它会重新创建相同数量的行,并从ViewState中恢复值。如果仅在会话中保存数据源(例如,不使用ViewState),则每次postback都需要重新绑定数据到网格中。因此,如果您创建类似于GridView的服务器控件,则Dino Esposito帖子中描述的方法将非常有用,因为它展示了如何创建类似于ASP.NET Server GridView控件的控件。


我的大多数控件都是手动呈现的(并且是纯HTML,而不是服务器控件),因此我不能指望控件保留自己的视图状态。 - Elad Lachmi

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