关于html+ashx开发中几个问题的解决方法

简介: 在跟html+ashx打交道的园友们肯定会发现,这种模式虽然优美,但在开发中会遇到一些难处理的地方。我也不例外,下面是自己在实际开发中总结出来的几条经验,希望跟大家分享,更希望得到大家的建议和更好的解决方法!     问题1:用委托字典代替switch...case。

在跟html+ashx打交道的园友们肯定会发现,这种模式虽然优美,但在开发中会遇到一些难处理的地方。我也不例外,下面是自己在实际开发中总结出来的几条经验,希望跟大家分享,更希望得到大家的建议和更好的解决方法!

 

  问题1:用委托字典代替switch...case。

  这个问题是在处理请求时发现的,大家肯定也不愿意在自己的项目中建许多的handler来处理那么多的请求,于是就想到在一个handler里处理多个请求,ajax请求中都加一个action的参数,在handler里根据这个action做相应的处理或返回相应的数据,这里肯定没有人用if...else来判断action,大多数人都会想到用switch...case,一开始我也是用的switch,但渐渐地发现,每个case不像一个代码块,不能为其中的变量提供一个独立的作用域!用龙珠中孙悟空的话“真是伤脑筋”。

  在网上搜了一下,也有不少人遇到这个问题。有个解决方法是把每个处理单独成handler里一个方法,这样清楚明了,但在ProcessRequest方法中要用反射调用对应的方法!自己对这个解决办法不太满意,于是想到了委托,想到了字典,把反射调用方法变成在字典里索引委托。

  首先在handler里声明一个私有的静态委托字典:

  static  Dictionary < string , Func < string >>  hs;

  然后用handler(一般处理程序的类)里静态构造函数初始化hs,更重要的是要在静态构造函数里添加处理方法:

  static  Handler() 
  {
    hs 
=   new  Dictionary < string , Func < string >> ();
    hs.Add(
" add " delegate ()
    {
      
int  id  =   int .Parse(req( " id " ));
      
string  title  =  req( " title " );
      
return   " add " ;
    });
    hs.Add(
" update " delegate ()
    {
      
int  id  =   int .Parse(req( " id " ));
      
string  title  =  req( " title " );
      
return   " update " ;
    });
  
}

   最后就是在ProcessRequest方法里调用了:

  context.Response.ContentType  =   " text/plain " ;
  HttpRequest req 
=  context.Request;
  
string  action  =  req[ " action " ].ToLower();
  
string  result  =  hs[action]();
  context.Response.Write(result);

  这样便避免了switch...case的变量作用域问题和反射的效率问题。关于上面用到的req()方法,我的想法是把公共的东西用静态方法提供,如:

   static   string  req( string  key)
  {
    
return  HttpContext.Current.Request[key];
  }
  
static   string  jss( object  obj)
  {
    JavaScriptSerializer JSS 
=   new  JavaScriptSerializer();
    
return  JSS.Serialize(obj);
  }

  

  问题2:权限问题。

  你肯定不愿自己的数据在用户没有登陆或登陆过期后还可以继续访问。这里假设登陆的用户用Session["user"]来存储,当然在handler里判断一下Session["user"]是很简单的事情,但问题是你如何让Session["user"]为null时的用户跳转到指定页(这里假设是登陆页login.html)。哈哈,这时你会不会想到用context.Response.Redirect ("login.html")这样一句话来解决呢!我的第一反映是这样的,但分析一下,ajax是请求数据的,这样做是让ajax去请求login.html这个页面,得到的结果应该是login.html的源代码才对,分析是这样分析的,可还是不死心,还是测试了一下,结果正如分析的那样,login.html的源代码做为ajax请求结果返回了!

  其实,大家心理明白,有一个很简单的方法,就是在Session["user"]为null时返回一个特定值,这里假设"unlogin",然后在每次ajax请求完成后判断返回值是不是"unlogin"。

这方法很简单,也很可靠,但很笨,很麻烦,可行性不高。于是我又想到了jquery.ajaxSuccess(),想用它来做统一处理,在我想到它的时候我就有点儿担心,jquery会不会是先调用具体请求的回调函数然后再调用这全局的回调函数呢?我带着这个疑问做了测试,结果也如预料那样先执行具体请求的回调再执行全局回调!没法办,只好查jquery的源码了~。在没压缩的jquery-1.4.2.js里找到了success()这方法,果然如此,改顺序后如下:

  function success() {  
     if  ( s. global  ) {
      trigger( 
" ajaxSuccess " , [xhr, s] );
    }            
    
//  If a local callback was specified, fire it and pass it the data
     if  ( s.success  &&  xhr.responseText != " unlogin "  ) {
      s.success.call( callbackContext, data, status, xhr );
    }
  }

  执行顺序是改好了,可跳转的代码写哪呢?每个页面写一次?不不,这不是我们写程序的风格,思来想去,写到jquery文件里(最下面)是一个可行的方法:

$(document).ajaxSuccess( function (event,xhr,settings){
    
if (xhr.responseText == " unlogin " ){
        window.top.location.href
= " /login.html " ;
    }
})

  很显示,不是每个页面的ajax请求都要求用户登陆,比如login.html页,所以判断时要排除不用登陆的页面:

  if  (HttpContext.Current.Request.UrlReferrer.ToString().ToLower().IndexOf( " login.html " ) <   0 )
  {
    
if  (HttpContext.Current.Session[ " user " ==   null )
    {
      HttpContext.Current.Response.Write(
" unlogin " );
      HttpContext.Current.Response.End();
    }
  }

 

  问题3:数据模板。

  真是什么东西需要,什么都东西就应运而生!在写这个随笔之前正好在园里看到了个jquery.tmpl的文章!tmpl的产生也正是解决这个问题的!我很自知这个方法没tmpl强大,但tmpl有一个问题没有解决,其实模板有两个主要的问题,1是如果模板存储在js里不好编辑,2是要把模板存储在哪里才方便设计时的视图呢!tmpl把模板存储在<script  type="text/x-jquery-tmpl"></script>标签中,应该说是解决了第一个问题,但我感觉第2个问题也是很重要的!想来想去,只能把模板直接存储在数据的容器标记里:

     < ul  id ="ulList" >
        
< li >< href ="somepage.html?id={ID}" > {Title} </ a >< br  />
            {Content}
</ li >
    
</ ul >

    把模板直接写在目标容器里,就像一条数据一样,美工调样式不是问题,程序加方法不是问题,这方法我看行!但js肯定不会直接操作这个模板吧,现在要做的就是把这个模板变成真的模板:

  $( function () {
    
var  ulList  =  $( " #ulList " );
    ulList.data(
" tpl " ,ulList.html()).empty();
  }

   把模板存储到容器的data里应该是再适当不过了,而且这个操作在页面加载完马上就做!然后把容器清空,让位给后来加载过来的真实数据。后台提供json数据,这个很简单:

     public   class  News
    {
        
public   int  ID {  get set ; }
        
public   string  Title {  get set ; }
        
public   string  Content {  get set ; }
    }
    
// handler里用了上面第一个问题的解决方法
  hs.Add( " getNews " delegate ()
  {
    List
< News >  list  =   new  List < News > () 
    {  
      
new  News(){ ID = 1 ,Title = " title1 " ,Content = " Content1 " },
      
new  News(){ ID = 2 ,Title = " title2 " ,Content = " Content2 " },
      
new  News(){ ID = 3 ,Title = " title3 " ,Content = " Content3 " },  
    };
    
return  jss(list);
  });

   前台取数据没什么好说的,这个很基本:

    $.get( " Handler.ashx?n= "   +  Math.random(), { action:  " getNews "  },  function (data) {
        
var  list  =  $.parseJSON(data);
        
var  ul  =  $( " #ulList " );
        
var  html  =   "" ;
        
for  ( var  i  =   0 ; i  <  list.length; i ++ ) {
            html 
+=  ul.data( " tpl " ).format(list[i]);
        }
        ul.html(html);
    })

   在填充数据的时候用了string.format这个方法,它在我js中的string.format  随笔里有记录,呵呵,这个我也没有想到,写format的时候让它支持json对象只是为了阅读方便,然而用到这如此合适!到这的时候我已兴奋不已了,测试结果如下:

  但当我加了事件后,我发现还不够好。如果在模板li里加上onclick="show({ID},'{Title}')",IE里刚打开页面的时候就会有js错误,这是为什么呢?问题在这个ID参数上,因为{ID}被看作json对象了,而它却是一个格式不对的json!  提示js错误也正常,'{Title}'没有错误是原因这里看作字符串参数了。这个js错误虽然不影响程序,但没有人不喜欢自己写的代码是没有js错误的! 解决方法很简单,像Title参数一样加引号就可以了,如果show方法里真的要数字类型,只好在那里转换一下喽!不过你肯定会发现,很多时候是不用转换的,甚至你还希望它就是个字符串类型呢!

  从没有这么认真的写过随笔,三个星期就休息了这一下午,没陪女朋友,没睡大觉,没找朋友喝酒,却老老实实地把它完成了!

 

另加:取数据模板可写成函数

function initTemplate(){
    $(".tplContainer").each( function() {  // 取出模板
        $( this).data("tpl", unescape($( this).html())).empty().removeClass("tplContainer");
    })

在容器里加.tplContainer{display:none},这样也不会加载时显示出模板了!

目录
相关文章
|
5月前
|
开发框架 前端开发 JavaScript
前端框架演进史:从HTML到现代化开发
前端框架演进史:从HTML到现代化开发
99 0
|
3月前
|
移动开发 前端开发 JavaScript
基于 HTML5 和 Canvas 开发的在线图片编辑器
基于 HTML5 和 Canvas 开发的在线图片编辑器
70 0
|
4月前
|
存储 移动开发 编解码
基于HTML5开发的Markdown在线编辑器
Markdown是一种轻量级标记语言,以其简洁易读的格式而备受程序员和作者们的青睐。随着互联网的发展,越来越多的在线Markdown编辑器应运而生,为用户提供了更加便捷、高效的写作和编辑环境。本文将探讨基于HTML5开发的Markdown在线编辑器的设计原理、功能特点以及技术优势。
106 4
|
5月前
|
关系型数据库 MySQL
web简易开发(二){html5+php实现文件上传及通过关键字搜索已上传图片)}
web简易开发(二){html5+php实现文件上传及通过关键字搜索已上传图片)}
|
5月前
|
存储 移动开发 编解码
基于HTML5开发的Markdown在线编辑器
Markdown是一种轻量级标记语言,以其简洁易读的格式而备受程序员和作者们的青睐。随着互联网的发展,越来越多的在线Markdown编辑器应运而生,为用户提供了更加便捷、高效的写作和编辑环境。本文将探讨基于HTML5开发的Markdown在线编辑器的设计原理、功能特点以及技术优势。
67 1
基于HTML5开发的Markdown在线编辑器
|
4月前
|
缓存 移动开发 前端开发
在PWA的开发中,HTML与CSS作为前端技术的基础,发挥着至关重要的作用
【6月更文挑战第14天】PWA(渐进式网页应用)借助HTML和CSS,提供接近原生应用的体验。HTML构建页面结构和内容,响应式设计适应各种设备,语义化标签提升可访问性,Manifest文件配置应用元数据,离线页面保证无网时体验。CSS则用于定制主题样式,创建动画效果,实现响应式布局,并管理字体和图标。两者协同工作,确保PWA在不同环境下的优秀性能和用户体验。随着前端技术进步,HTML与CSS在PWA中的应用将更加深入。
43 2
|
5月前
|
开发工具 CDN 容器
基于Html+腾讯云播SDK开发的m3u8播放器
周末业余时间在家无事,学习了一下腾讯的云播放sdk,并制作了一个小demo(m3u8播放器),该在线工具是基于腾讯的云播sdk开发的,云播sdk非常牛,可以支持多种播放格式。
225 1
|
4月前
|
机器学习/深度学习 Web App开发 前端开发
【Web开发】深度学习HTML(超详细,一篇就够了)
【Web开发】深度学习HTML(超详细,一篇就够了)
22 0
|
5月前
|
前端开发 JavaScript UED
【专栏:HTML与CSS移动端开发篇】移动端触摸事件与手势识别
【4月更文挑战第30天】本文探讨了移动端触摸事件和手势识别在网页开发中的重要性。介绍了基础触摸事件如`touchstart`, `touchmove`, `touchend`, `touchcancel`及相关属性。文章列举了处理触摸事件的方法,包括单点触摸、多点触摸、滑动、长按、捏合缩放、旋转检测和事件代理。建议使用第三方库如Hammer.js简化手势处理,并分享了最佳实践,如避免意外触摸、提供视觉反馈、考虑性能和跨设备测试。理解并有效利用这些技术能提升用户交互体验。
195 7
|
5月前
|
移动开发 前端开发 JavaScript
:掌握移动端开发:HTML5 与 CSS3 的高效实践
:掌握移动端开发:HTML5 与 CSS3 的高效实践 “【5月更文挑战第6天】”
73 1