我需要从数据库中检索一条记录,将其显示在网页上(我正在使用 ASP.NET),但将该记录中的 ID(主键)存储在某处,以便稍后我可以使用该 ID 返回数据库(也许做一个更新)。
我知道可能有几种方法可以做到这一点,例如将 ID 存储在 ViewState 或隐藏字段中,但是最好的方法是什么,我可能会选择这种方法而不是其他方法的原因是什么?
这取决于。
你关心是否有人看到记录ID?如果你这样做了,那么隐藏字段和视图状态都不合适;您需要将其存储在会话状态中,或加密视图状态。
您是否关心是否有人使用伪造的 id 提交表单?如果这样做,则不能使用隐藏字段(并且您需要将 CSRF 保护视为奖励)
您是否希望它不变但不关心它是否可以查看(通过一些工作)?在您的页面(或全局)上使用视图状态并设置 enableViewStateMac="true"
想要隐藏和保护它但不能使用会话状态?通过设置以下 web.config 条目来加密您的视图状态
<pages enableViewState="true" enableViewStateMac="true" />
<machineKey ... validation="3DES" />
您希望最终用户知道 ID 吗?例如,如果 id 值是来自数据库的标准 1,1 种子,我可以查看数字并查看您拥有多少客户。如果您加密该值(就像视图状态一样),我会发现解密密钥要困难得多(但并非不可能)。
另一种方法是将其存储在会话中,这将对您的应用程序产生(如果它只是一个整数,则非常小)性能影响,但这意味着我作为用户永远不会看到该主键。它还将对象暴露给您的应用程序的其他部分,您可能希望也可能不希望它被暴露(会话对象保留直到清除,经过设定的时间(如 5 分钟)或浏览器窗口关闭 - 以较早发生者为准.
每次回发后,视图状态值都会在客户端上造成额外的负载,因为视图状态不仅会保存页面的对象,而且如果您使用后退按钮,还会记住对象。这意味着在每次回帖后,它的视图状态会变得更大且更难使用。它们只会存在于他的页面上,直到浏览器转到另一个页面。
每当我像这样在页面中存储一个 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”访问该变量。
ViewState 是一个选项。它仅对您所在的页面有效。它不携带对其他资源(如 Session 对象)的请求。
隐藏字段也可以工作,但是您正在向任何聪明到可以查看页面源代码的人泄露有关您的应用程序的少量信息。
您还可以将整个记录存储在 ViewState 中,并且可能避免再次往返服务器。
我个人对在会话中添加任何内容持怀疑态度。我们的工作进程循环了太多次,我们丢失了会话状态。
正如您描述的问题,我会将其放在隐藏字段或页面的视图状态中。
此外,在确定将此类数据放在何处时,请始终查看数据的范围。它的范围是单个页面还是整个会话?如果对我们来说答案是“会话”,我们将其放入 cookie 中。(免责声明:我们在知道启用了 cookie 的情况下编写内部网应用程序。)
如果它是一个简单的 id 将选择在查询字符串中传递它,那么您不需要进行回发,并且页面更容易被用户和搜索引擎访问。
Session["MyId"]=myval;
它会更安全一些,并且本质上提供与将其置于视图状态中相同的机制
我倾向于将类似的东西粘贴在隐藏的领域中,只需做一点
<asp:label runat=server id=lblThingID visible=false />