问:我有一个页面,它可以基于用户筛选器来显示 DataGrid。当用户单击 DataGrid 中某个特定行的 Edit 按钮时,我使用 Response.Redirect 将用户重定向到他更新数据的详细内容页面。现在,我想将我的用户带到第一页,并基于他先前所选的相同筛选器来向他显示 DataGrid。这样做的最佳方法是什么呢?我的其他要求如下:
• 我希望在 Page1.aspx 中保留一些值,之后转到 Transfer.aspx,然后当我回到 Page1.aspx 时,我希望使用这些值。
• 我需要使用查询字符串将值从 Page1.aspx 传递到 Transfer.aspx 并传递回来。
• 最后,我希望获得调用页面的 URL。我还必须考虑性能。
我知道我可以将筛选器选项存储在会话状态变量中,然后当用户返回到该页面时,DataGrid 可以使用这些会话变量。然而,会话变量依赖于 cookie,因此如果用户没有启用 cookie,则会出现问题。
答:解决您的问题的一种方法是使用 Server.Transfer 和 Context.Items。下面是您将在 Page1.aspx 中使用的代码:
Server.Transfer("Transfer.aspx");
并且,在 Transfer.aspx 中您可以使用:
Server.transfer 在服务器端执行传输;页面不会返回到它们之间的客户端,因此该方法可避免将 302 页发送到导致客户端与服务器之间的额外往返行程的客户端。
当处理过程发生在服务器端时,可以获得请求的 HttpContext 实例。一旦将页面发送到客户端,该特定的 HttpContext 就不再有效。它不会在与客户端的往返行程之间保留。因此,如果您转到 Transfer.aspx 然后使用 Server.Transfer 返回到 Page1.aspx,则上下文仍然可用。如果您让客户端看到 Transfer.aspx,那么它就不可用了。
对了,您也可以使用查询字符串来传递值。您可以将该方法与 Server.Transfer 和 Response.Redirect 一起使用,这是一种来回传递值的好方法。使用 Server.Transfer,客户端实际上不会看到查询字符串,但是如果使用 Response.Redirect,它们就会看到查询字符串。还有一些方法可以将您的值编码到查询字符串中,以便可以加密重要的信息。
您还应该了解有关 Server.Transfer 的另一个情况。在 ASP.NET 1.0 中,如果这是初始请求,则会将传输保留为 POST。在 ASP.NET 1.1 中,除非将页面传输给它本身,否则它始终是 GET,因此您必须使用查询字符串,因为 Form 集合已不再可用。
要获得调用页面的 URL,您可以选择使用 Request.UrlReferrer.AbsoluteUri(获得相关页面路径和查询字符串),也可以选择使用 Request.UrlReferrer.AbsolutePath(只获得相关页面路径)。
在 Page1.aspx 的页面 Load 事件中,因为在用户首次键入该页面的 URL 时没有引用站点,所以 Request.UrlReferrer 将为空。因此,任何访问诸如 AbsoluteUri 之类的属性的尝试都将导致异常。如果 Page.IsPostBack 为真,则只需在 Page1.aspx 中执行以下代码即可避免此问题。您可以使用如下代码:
Request.UrlReferrer.AbsoluteUri : string.Empty;
使用 UrlReferrer 的唯一实际问题是,即使实际引用该页面,也不能保证它就在那里,因为一些防火墙和私有软件会筛选出该值。您可以将诸如“ReferrerUrl=MyPageName.aspx”之类的查询字符串参数附加到 Response.Redirect 调用的末尾。
有关详细信息,请参见 HttpServerUtility.Transfer 方法和 HttpContext 类。
