【问题标题】:Where to store web custom control dataWeb 自定义控件数据的存储位置
【发布时间】:2012-11-23 16:25:38
【问题描述】:

我正在创建一个扩展 WebControl 的自定义控件。这个 Web 控件允许消费者在标记中定义列的集合,如下所示:

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

并将 IEnumerable 放入 DataSource 属性中,然后将其呈现到表中。 该控件还允许分页。 DataSource 中的 IEnumerable 是完整列表,我一次显示列表的一页。我已经将当前页面、每页的行数等保存到视图状态。我是否也应该将完整列表放入视图状态?也许会话? 这个列表可能会变得有点庞大。也许使用随机密钥保存在会话中,该密钥保存在视图状态中? 这里的最佳做法是什么?

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

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

【问题讨论】:

    标签: c# asp.net viewstate


    【解决方案1】:

    确实,并非所有IEnumerable 实例都可以序列化。

    如果查询运行起来很便宜,我不会保留整个数据集,而只是针对不同的页面或更改排序顺序再次运行查询。

    如果您将数据放在视图状态中,您最终会得到大页面。如果您没有很多用户,会话状态可能是可以接受的,但是具有大量用户的大型数据集将无法很好地扩展。如果我将一百万行绑定到您的控件怎么办?或者,如果您的控件用于中继器并在一个页面上显示 100 次怎么办?

    您确定需要保留数据吗?这不是过早优化吧?

    请记住,您的控件是一个 UI 组件。视图状态应该包含足够的信息来维持 UI 状态。状态更改(例如:切换到不同的结果页面)是您的控件应将责任移交给数据源的事情。

    看看好老GridView。它会显示你给它的东西并记住它。如果您正在使用分页,那么它会引发一个事件,说“用户已更改页面;给我第 x 页数据”。对我来说,这是 UI 控件的最佳实践。

    【讨论】:

    • 这或多或少是我最终做的。由于数据集不是很大,我只是将在每个回发上设置 DataSource 属性的责任传递给消费页面,并且我只在 ViewState 中存储我需要将 DataSource 恢复到其先前状态的内容。
    【解决方案2】:

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

    基本上,如果您创建像 ASP.NET gridview 这样的控件,那么它会将值存储在视图状态中。更清楚地说,它是创建在视图状态中保存分配值的 DataRow 控件的数量。在回发期间,它重新创建相同数量的行,并从视图状态恢复值。如果您将仅保存数据源,例如在会话中不使用视图状态,那么您将需要在每次回发期间将数据重新绑定到您的网格。因此,如果您创建类似于 gridview 的服务器控件,那么 Dino Esposito 帖子中描述的方法将非常有用,因为它展示了如何创建类似于 ASP.NET Server GridView 控件的控件。

    【讨论】:

    • 好吧,我的大部分控件都是手动呈现的(并且是纯 HTML,而不是服务器控件),所以我不能指望控件保留自己的视图状态。
    猜你喜欢
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    相关资源
    最近更新 更多