我应该在ViewState中存储数据库ID字段吗?
我需要从数据库中检索一条记录,将其显示在网页上(我使用的是ASP.NET),但将从该记录中存储的ID(主键)存储在某个地方,以便稍后可以使用该ID返回数据库也许要进行更新)。
我知道可能有几种方法可以做到这一点,例如将ID存储在ViewState或者隐藏字段中,但是最好的方法是什么?为什么我会选择此方法而不是其他方法呢?
解决方案
Session["MyId"]=myval;
这样会更安全一些,并且基本上提供与将其置于视图状态时相同的机制
ViewState是一个选项。仅对我们所在的页面有效。它不会携带对其他资源(如Session对象)的请求。
隐藏的字段也可以工作,但是我们正在泄漏信息,很少有信息与应用程序共享给足够聪明的人来查看页面的源代码。
我们也可以将整个记录存储在ViewState中,并避免再次往返服务器。
我个人对在会议中提出任何意见非常持怀疑态度。我们的工作进程已经循环了很多次,我们丢失了会话状态。
当我们描述问题时,我会将其放在隐藏字段或者页面的视图状态中。
另外,在确定将数据放置在何处时,请始终查看数据范围。它的作用域是单个页面还是整个会话?如果答案是我们的"会话",则将其放入Cookie中。 (免责声明:我们在知道启用Cookie的位置编写Intranet应用。)
这取决于。
我们是否在乎是否看到记录ID?如果这样做,则隐藏字段和viewstate都不适用;否则,将不可用。我们需要将其存储在会话状态或者加密视图状态。
我们是否在担心有人提交带有伪造身份证的表格?如果这样做,那么我们将无法使用隐藏字段(并且我们需要将CSRF保护视为一项奖励)
我们是否希望它保持不变,但不关心它是否可供观看(需要做一些工作)?使用viewstate并在页面上(或者全局)设置enableViewStateMac =" true"
希望它被隐藏和保护但不能使用会话状态?通过设置以下web.config条目来加密viewstate
<pages enableViewState="true" enableViewStateMac="true" /> <machineKey ... validation="3DES" />
我倾向于将类似的东西贴在隐藏的区域中
<asp:label runat=server id=lblThingID visible=false />
如果其简单ID将选择以querystring传递它,则我们无需进行回发,并且用户和搜索引擎可以更轻松地访问页面。
我们是否希望最终用户知道ID?例如,如果id值是数据库中的标准1,1种子,我可以查看该数字并查看我们有多少客户。如果我们对值进行加密(如viewstate可以),我将发现解密密钥变得更加困难(但并非不可能)。
另一种方法是将其存储在会话中,这会给应用程序带来性能(如果只是整数,则很小),但是这意味着我作为用户从未见过该主键。它还会将对象公开给应用程序的其他部分,我们可能希望或者不希望其公开(会话对象会一直保留,直到清除,经过设置的时间(如5分钟)或者关闭浏览器窗口为止,以较早发生者为准。
每次回发后,视图状态值都会给客户端造成额外的负担,因为viewstate不仅会保存页面的对象,而且如果使用"后退"按钮也会记住对象。这意味着每回发一次贴图,viewstate就会变得更大并且更难使用。它们将仅存在于该页面上,直到浏览器转到另一个页面为止。
每当我在这样的页面中存储ID时,我总是会创建一个属性
public int CustomerID { get { return ViewState("CustomerID"); } set { ViewState("CustomerID") = value; } }
或者
Public Property CustomerID() As Integer Get Return ViewState("CustomerID") End Get Set(ByVal value As Integer) ViewState("CustomerID") = value End Set End Property
这样,如果我们决定将其从Viewstate更改为会话变量或者隐藏的表单字段,这只是在属性引用中进行更改的一种情况,其余页面可以使用" Page.CustomerID"访问该变量。