繁体   English   中英

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

[英]Saving values server side vs. using Sessions and Request.QueryString in ASP.net

我正在制作一个简单的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 WebForms 您的用例不完整,但我会在这里展示一些替代方案来实现您的目标。 如果您提供进一步的信息,我很乐意更新我的答案。

在我们开始之前,让我说清楚: HTTP是无状态的 理解这个基本规则非常重要。 这意味着您的服务器将收到请求,将其发送到您的应用程序(和.NET进程),获取生成的页面(和资产)并将其发送回客户端(主要是浏览器)。 故事结局。 几乎 )您为响应请求而创建的所有内容都将丢失。 这就是为什么我们可以选择在请求中存储对象/值的位置

服务器端会话

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

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

GET参数(AKA QueryString)

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

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

的ViewState

您可能听说过它,它是使WebForms如此可爱(以及如此可恶)的引擎。 默认情况下,页面上的每个控制器都会将其状态序列化为viewstate,这是一个巨大的隐藏字段,其中包含页面上的加密数据。 继续,单击“查看源”并查找它。 请不要尖叫。 您可以像Session一样将任意数据添加到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值,那么我可以为此页面创建一个书签,然后点击书签,页面将在我之前离开时工作。 根据内存缓存(可能存在或不存在),不能保证我的书签每次都能正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM