保存服务器端的值与在ASP.net中使用Sessions和Request.QueryString相比

本文关键字:Sessions Request 相比 QueryString net 服务器端 ASP 保存 | 更新日期: 2023-09-27 18:20:20

我正在制作一个简单的asp.net应用程序,它显示可以根据几个不同参数过滤的数据。因此,当前选择的不同过滤器需要保存在某个位置。我是.NET的新手,想知道保存这些信息的最佳方式。我注意到一位同事将Request.QueryString与Sessions字典结合使用。页面加载上有这样的东西:

protected void Page_Load(object sender, EventArgs e) 
{
    if (Request.QueryString["Category"] != null &&
        Request.QueryString["Value"] != null)
    {
        string Category = Request.QueryString["Category"];
        string CategoryValue = Request.QueryString["Value"];
        // selectedFacets is the server side dictionary
        selectedFacets.Add(Category, CategoryValue);                    
    }
 }

当用户按下网页上的按钮,更新URL时,此处的QueryString会发生更改。

我的问题是,当我们使用QueryString的目的只是保存一个值服务器端时,为什么还要使用它呢?不仅仅是让按钮成为一个asp控制器更容易,比如:

protected void exampleCatexampleVal_Button_onClick(object sender, EventArgs e) 
{
     selectedFacets.Add(exampleCat, exampleVal);
}

Sessions字典也有类似的业务:它只是用来将一堆值保存到服务器上的变量中,那么为什么要首先使用它呢?我相信这是有充分理由的,但现在他们所做的似乎过于复杂了。谢谢!

保存服务器端的值与在ASP.net中使用Sessions和Request.QueryString相比

根据您的代码示例,我理解您所说的是ASP.NET WebForms。您的用例并不完整,但我将在这里展示一些实现您目标的替代方案。如果你提供更多信息,我很乐意更新我的答案。

在我们开始讨论之前,让我明确一点:HTTP是无状态的。理解这个基本规则非常重要。这意味着你的服务器将收到一个请求,将其发送到你的应用程序(和.NET进程),获得结果页面(和资产),并将其发送回客户端(主要是浏览器)。故事结束了。(几乎)您为响应请求而创建的所有内容都将丢失。这就是为什么我们在上有在请求中存储对象/值的选项。

服务器端会话

这是最简单的选择之一。你只需调用this.Session.Add("key", object),它就完成了。让我们深入研究一下:

  • 它将使用服务器资源。也就是说,你使用会话的次数越多,你的应用程序消耗的内存(以及所需的其他资源)就越多
  • 它将更难扩展,因为数据将在服务器内存中。根据您的硬件,垂直缩放可能是一种选择,但水平缩放将受到限制。您可以使用会话服务器,也可以将会话存储在SQL server数据库上,但它的效率将不再那么高
  • 它附加到您的客户端会话。如果用户打开另一个浏览器或向他的朋友发送链接,它将丢失
  • 它相对安全。我之所以说,是因为下面的选项。至少是服务器端

GET参数(又名QueryString)

这是另一种选择,你已经知道了。您可以使用查询字符串(?that=stuff&on=the&URL=youKnow)来回发送数据。

  • 它被限制为2000个字符,并且必须是可序列化的。这就是为什么你可能不会在那里放一个DataGrid
  • 用户可以更改它。注意始终清除QueryString中的数据
  • 用户可以自由地将链接添加书签或发送给朋友,内容也一样。很好,请注意

ViewState

你可能听说过,正是这个引擎让WebForms变得如此可爱(如此可恨)。默认情况下,页面上的每个控制器都会将其状态序列化为viewstate,这是一个巨大的隐藏字段,页面上有加密的数据。继续,点击"查看来源"并寻找它。请不要尖叫。您可以像会话一样将任意数据添加到ViewState。

  • 它在客户端不要相信它
  • 它将在每次请求时来回发送,因此会消耗额外的带宽
  • 对每个请求/响应进行反序列化/序列化需要一些时间
  • 数据必须是可序列化的(你知道我的意思)

所以,到目前为止,我希望你有足够的信息来做出自己的决定。如果我错过了什么,请告诉我。

先看一下MSDN的这篇文章。我通读了一遍,它可能会为你回答你的问题。

http://msdn.microsoft.com/en-us/magazine/cc300437.aspx

您缺少的是asp.net页面生命周期的工作方式:

http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx

问题是,"服务器变量"不会在回发(AFAIK)之间持续存在。它只在那一页里面有用。一旦页面在循环结束时被丢弃,该字典就不见了。所以,如果你以后想使用它,你必须把它存放在某个地方。我引用的这篇文章向您展示了可以存储信息以将其持久化的所有位置,以及存储信息的位置取决于您需要信息持久化多长时间,以及应该有多少用户可以访问它

现在,当然,如果你不想保留那个字典,那么当然,只需将其存储在页面变量中即可。这很好。没有理由再保留那些你不再需要的数据。

最好记住,在从数据库或单独的进程服务(StateServer)存储和检索会话状态时,性能会受到轻微影响。如果会话状态存储在内存中,则无法将应用程序扩展到web服务器场,这将浪费web服务器中有价值的内存。

另一方面,使用查询字符串值不会浪费内存和资源,速度很快,而且不必考虑管理会话状态。它提供SEO的好处,并允许书签/收藏夹。

但是,使用查询字符串只能存储有限数量的数据(WWW常见问题解答:URL的最大长度是多少)。如果敏感数据被暴露,或者恶意用户试图在代码中发现错误处理URL值的错误,它也会带来安全风险。SQL注入攻击就是其中一种情况。您可以对敏感值进行加密。

总的来说,这里有很多方面需要考虑。

使用查询字符串值的好处之一是,如果您需要存储在应用程序中的书签/收藏夹,用户可以直接导航到页面,并在没有内存缓存的情况下将某些值传递到页面中。以以下为例:

我有一个产品页面,它显示了可以按类别名称筛选的产品的网格视图。如果我在查询字符串中使用categoryId值,那么我可以为该页面创建书签,然后稍后单击书签,该页面将像我之前离开时一样工作。取决于内存中的缓存,它可能存在也可能不存在,并不能保证我的书签每次都能工作。