ASP.NET:"返回"按钮的解决方案摸索

简介:

做过网站或WEB系统的,肯定都曾在自己的页面中用过“返回”按钮。我也不例外,在多次的开发中,我曾经思索:这个小小的“返回”按钮,应该以怎样的代码实现比较好。

  先说说自己最常使用的,也是最常见最无脑的。如:

1           protected  void Back()
2          {
3              Response.Redirect( " CurrList.aspx " );
4          }

   有时候,当返回的页面的是一个带分页的页面时,则需要在进入页面时传入分页信息,然后在返回时取出这些值。比如:

1       private  void Goback()
2      {
3           string  size  =  Request.QueryString[ " size " ];
4           string  index  =  Request.QueryString[ " index " ];
5             Response.Redirect( " SellInfoDisplay.aspx?size= "   +  size  +   " &index= "   +  index );
6      }

          用的最多的,无非以上了。

  有的时候,再复杂一些,比如一个页面可以从不同的页面跳入,那么,还得再记录哪个页面来的,返回的时候,再判断判断。

  再有的时候,A页面跳到B页面,B页面再跳到C页面,这个时候想要连着两次返回到A页面,要写的代码就多了。

  那么,这个小小的“返回”按钮有没有什么好的方法去处理呢?

  首先我尝试了这样的方法:

1  history.go( - 1 );

   曾经在某些页面中用过这样的方法,似乎也没什么问题。但这个方法是有使用范围限制的,通常它适合用在静态页面。另外,当跳转之前页面执行了某个脚本,而这个脚本中alert了一下,此时用这个方法跳转回来的时候,我发现它又alert了一下,这显然不行。

  接着我又尝试了这样的方法:

1       protected  void SaveCurrURL() 
2      { 
3          Session[ " prevURL " =  Request.UrlReferrer.PathAndQuery; 
4      } 
5   
6       protected   string   GetCurrURL() 
7      { 
8           return  Session[ " prevURL " ].ToString(); 
9      }
10  
11       protected  void Back()
12      {
13          Response.Redirect(this.GetCurrURL());
14      }

   前两个方法写在自定义的页面基类中,并且我约定了系统中总是将分页,查询,排序等参数信息保存在URL中。接着我制作了对应的分页控件,正当我沾沾自喜,以为大功告成的时候,又一个问题出现了。

  Request .UrlReferrer .PathAndQuery 这句代码似乎会有失灵的时候。

  经过几次尝试,发现问题是这样的:

       假设从A页面跳转至B页面,那么A页面的方式如果是以脚本的方式进行跳转的话,那么在B页面调用SaveCurrURL方法是获取不到预期的值的,比如(location.href=。。。。),而在A页面以超链接的方式进行跳转的话,则可以顺利获取到。

         这是何故?又怎麽办呢?我们知道,用户点击超链接属于用户主动行为,而脚本触发,则属于被动行为,有时候某些被动行为会因为安全方面的考虑而受到重重阻碍。我们可以以脚本的方式触发超链接元素的onclick事件,确很难模拟用户直接点击超链接的效果(我认为是不能)。

        后来我决定退一步,牺牲一下性能,将代码改成Session["prevURL"] = Request.Url.PathAndQuery;

        并且为了支持两级的返回,最后的代码是这样的

1       protected  void SaveCurrURL(bool first)
2      {
3           if  (Session[ " prevURL " ==  null)
4              Session[ " prevURL " =   new   string [ 3 ];
5           string [] urls  =  ( string [])Session[ " prevURL " ];
6           if  (first)
7          {
8              urls[ 0 =  Request.Url.PathAndQuery;
9              urls[ 1 =  null;
10              urls[ 2 =  null;
11          }
12          else
13         {
14               if  (urls[ 1 ==  null)
15                  urls[ 1 =  Request.Url.PathAndQuery;
16              else
17                 urls[ 2 =  Request.Url.PathAndQuery;
18          }
19          Session[ " prevURL " =  urls;
20      }
21       ///< summary >
22   ///  获取上次保存的URL23  ///</ summary >
24   ///< returns ></ returns >
25       protected   string   GetCurrURL()
26      {
27           string [] urls  =  ( string [])Session[ " prevURL " ];
28           for  ( int  i  =   2 ; i  >=   0 ; i -- )
29          {
30               if  (urls[i] ! =  null)
31              {
32                   string  url  =  urls[i - 1 ];
33                  urls[i]  =  null;
34                  urls[i  -   1 =  null;
35                  Session[ " prevURL " =  urls ;
36                   return  url;
37              }
38          }
39           throw   new  Exception( "" );
40      }

     最终的代码费了我不少心思,为了使session保持小巧,我用了string数组,而不是string list,为了支持两级返回,我将数组的长度设为3,这是有原因的。

  它们是这样的使用方式,假设有A\B\C 3个页面,

  A可以跳到B,B可以跳到C,C可以返回B,B可以返回A。

  那么在A页面,这是一个起点页面,调用SaveCurrURL传入TRUE参数,B和C页面的参数为FALSE,注意C页面也要调用,这属于一个瑕疵。

  在B和C的返回按钮中,不论他们是不是从A跳过来的,也不论他们处与第2个页面还是第3个页面,统统调用

  Response.Redirect(this.GetCurrURL ());

  最后,别忘了在if (!IsPostBack)中调用Save函数.

  以上便是我对“返回”功能的小小尝试,只能说支持一定的使用范围,有一定的简化作用和通用的处理方式。当然它没有经过严格的测试,也希望大牛们能提供更好的方案。

  修改了一下:

  有人提出服务器重定向不好,我也觉得,所以又改了一下,不用Button 用HyperLink,当然代码也要修改

1       protected  void SaveCurrURL(bool first)
2      {
3           if  (Session[ " prevURL " ==  null)
4              Session[ " prevURL " =   new   string [ 3 ];
5           string [] urls  =  ( string [])Session[ " prevURL " ];
6           if  (first)
7          {
8              urls[ 0 =  Request.Url.PathAndQuery;
9              urls[ 1 =  null;
10              urls[ 2 =  null;
11          }
12          else13         {
14               if  (urls[ 1 ==  null)
15                  urls[ 1 =  Request.Url.PathAndQuery;
16               else   if  (urls[ 2 ==  null)
17                  urls[ 2 =  Request.Url.PathAndQuery;
18              else
19                 urls[ 2 =  null ;
20          }
21          Session[ " prevURL " =  urls;
22      }
23       ///< summary >
24   ///  获取上次保存的URL
25  ///</ summary >
26   ///< returns ></ returns >
27       protected   string   GetCurrURL()
28      {
29           string [] urls  =  ( string [])Session[ " prevURL " ];
30           for  ( int  i  =   2 ; i  >=   0 ; i -- )
31          {
32               if  (urls[i] ! =  null)
33              {
34                   string  url  =  urls[i - 1 ];
35                  Session[ " prevURL " =  urls;
36                   return  url;
37              }
38          }
39           throw   new  Exception( "" );
40      }

   URL保存和获取方法都稍微了改了一下。

  现在在有返回按钮的页面上这样用:

1        this.SaveCurrURL( false  );
2        lbBack.NavigateUrl  =  this.GetCurrURL();

   这样就避免了服务器重定向。提高了性能。










本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/735603,如需转载请自行联系原作者
目录
相关文章
|
开发框架 .NET 数据库连接
win2016下asp无法连接access的解决方案
win2016下asp无法连接access的解决方案
496 0
win2016下asp无法连接access的解决方案
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
219 3
|
3月前
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
190 1
|
4月前
|
存储 安全 物联网
.NET 跨平台工业物联网网关解决方案
【9月更文挑战第28天】本文介绍了利用 .NET 构建跨平台工业物联网网关的解决方案。通过 .NET Core 和多种通信协议(如 MQTT 和 Modbus),实现工业设备的高效接入和数据采集。系统架构包括设备接入层、数据处理层、通信层、应用层和数据库层,确保数据的准确采集、实时处理和安全传输。此外,还详细阐述了设备身份认证、数据加密及安全审计等机制,确保系统的安全性。该方案适用于不同操作系统和工业环境,具备高度灵活性和扩展性。
117 1
|
5月前
|
API C#
.NET电子邮件高效处理解决方案
.NET电子邮件高效处理解决方案
|
6月前
|
监控 Linux C#
【干货分享】.NET人脸识别解决方案
【干货分享】.NET人脸识别解决方案
115 0
|
Java
JAVA 端口被占用 报错解决方案:java.net.BindException: Address already in use: bind
JAVA 端口被占用 报错解决方案:java.net.BindException: Address already in use: bind
300 0
|
8月前
|
Windows
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
1265 0
|
8月前
|
消息中间件 存储 NoSQL
.NET开源的处理分布式事务的解决方案
.NET开源的处理分布式事务的解决方案
131 0
|
SQL 监控 NoSQL
一个.Net Core开发的,撑起月6亿PV开源监控解决方案
一个.Net Core开发的,撑起月6亿PV开源监控解决方案
80 0