本文讲述使用Senparc.Weixin框架来快速处理各种接收事件推送。这里的消息指的是传统的微信公众平台消息交互,微信用户向公众号发送消息后,公众号回复消息给微信用户。包括以下类型:

1 subscribe/unsubscribe: 关注/取消关注事件
2 scan: 扫描带参数二维码事件
3 location: 上报地理位置事件
4 click: 自定义菜单事件
    1) click: 点击菜单拉取消息时的事件推送
    2) view: 点击菜单跳转链接时的事件推送
    3)  scancode_push:扫码推事件的事件推送
    4)  scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框的事件推送
    5)  pic_sysphoto:弹出系统拍照发图的事件推送
    6)  pic_photo_or_album:弹出拍照或者相册发图的事件推送
    7)  pic_weixin:弹出微信相册发图器的事件推送
    8)  location_select:弹出地理位置选择器的事件推送

实现非常简单,自定义一个继承MessageHandler的类,重写这些类型的方法即可。注意:DefaultResponseMessage必须重写,用于返回没有处理过的消息类型(也可以用于默认消息,如帮助信息等);其中所有原OnXX的抽象方法已经都改为虚方法,可以不必每个都重写。若不重写,默认返回DefaultResponseMessage方法中的结果。

下面详细介绍实现步骤:

1. 添加index页面

private readonly string Token = ConfigurationManager.AppSettings["token"];//与微信公众账号后台的Token设置保持一致,区分大小写。

       protected void Page_Load(object sender, EventArgs e)

       {

           string signature = Request["signature"];

           string timestamp = Request["timestamp"];

           string nonce = Request["nonce"];

           string echostr = Request["echostr"];

           if (Request.HttpMethod == "GET")

           {

               //get method - 仅在微信后台填写URL验证时触发

               if (CheckSignature.Check(signature, timestamp, nonce, Token))

               {

                   WriteContent(echostr); //返回随机字符串则表示验证通过

               }

               else

               {

                   WriteContent("failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, Token) + "。" +

                               "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。");

               }

               Response.End();

           }

           else

           {

               //post method - 当有用户想公众账号发送消息时触发

               if (!CheckSignature.Check(signature, timestamp, nonce, Token))

               {

                   WriteContent("参数错误!");

                   return;

               }

               //设置每个人上下文消息储存的最大数量,防止内存占用过多,如果该参数小于等于0,则不限制

               var maxRecordCount = 10;

               //自定义MessageHandler,对微信请求的详细判断操作都在这里面。

               var messageHandler = new CustomMessageHandler(Request.InputStream, maxRecordCount);

 

               try

               {

                   //测试时可开启此记录,帮助跟踪数据,使用前请确保App_Data文件夹存在,且有读写权限。

                   messageHandler.RequestDocument.Save(

                       Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Request_" +

                                      messageHandler.RequestMessage.FromUserName + ".txt"));

                   //执行微信处理过程

                   messageHandler.Execute();

                   //测试时可开启,帮助跟踪数据

                   messageHandler.ResponseDocument.Save(

                       Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Response_" +

                                      messageHandler.ResponseMessage.ToUserName + ".txt"));

                   WriteContent(messageHandler.ResponseDocument.ToString());

                   return;

               }

               catch (Exception ex)

               {

                   //将程序运行中发生的错误记录到App_Data文件夹

                   using (TextWriter tw = new StreamWriter(Server.MapPath("~/App_Data/Error_" + DateTime.Now.Ticks + ".txt")))

                   {

                       tw.WriteLine(ex.Message);

                       tw.WriteLine(ex.InnerException.Message);

                       if (messageHandler.ResponseDocument != null)

                       {

                           tw.WriteLine(messageHandler.ResponseDocument.ToString());

                       }

                       tw.Flush();

                       tw.Close();

                   }

                   WriteContent("");

               }

               finally

               {

                   Response.End();

               }

           }

       }

       private void WriteContent(string str)

       {

           Response.Output.Write(str);

       }

1)当Get请求时,调用 CheckSignature.Check(signature, timestamp, nonce, Token) 方法验证url接入, 详情参考 用c#开发微信(1)服务号的服务器配置和企业号的回调模式 - url接入 (源码下载)

2)  当有Post请求过来时,调用自定义MessageHandler类,对微信请求的详细判断操作都在这里面。

var messageHandler = new CustomMessageHandler(Request.InputStream, maxRecordCount);

messageHandler.Execute();

2. 自定义消息处理类

定义CustomMessageHandler继承MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>

public partial class CustomMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>

{

    public CustomMessageHandler(Stream inputStream, int maxRecordCount = 0)

        : base(inputStream, null, maxRecordCount)

    {

        WeixinContext.ExpireMinutes = 3;

    }

    public override void OnExecuting()

    {

        //测试MessageContext.StorageData

        if (CurrentMessageContext.StorageData == null)

        {

            CurrentMessageContext.StorageData = 0;

        }

        base.OnExecuting();

    }

    public override void OnExecuted()

    {

        base.OnExecuted();

        CurrentMessageContext.StorageData = ((int)CurrentMessageContext.StorageData) + 1;

    }

}

3. 分别重写几种接收事件推送

我们可以通过重写MessageHandler里的这几种类型方法来处理我们的业务,当然也可以只重写需要的部分类型,不需要的类型可以不重写,只需要定义一个统一的DefaultResponseMessage

public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)

{

    //所有没有被处理的消息会默认返回这里的结果

    var responseMessage = this.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "这条消息来自DefaultResponseMessage。";

    return responseMessage;

}

下面分别就这几种类型,各写一个例子:

1) 关注事件

/// <summary>

        /// 订阅(关注)事件

        /// </summary>

        /// <returns></returns>

        public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)

        {

            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);

            responseMessage.Content = GetWelcomeInfo();

            return responseMessage;

        }

2) 取消关注事件

/// <summary>

        /// 退订

        /// 实际上用户无法收到非订阅账号的消息,所以这里可以随便写。

        /// unsubscribe事件的意义在于及时删除网站应用中已经记录的OpenID绑定,消除冗余数据。并且关注用户流失的情况。

        /// </summary>

        /// <returns></returns>

        public override IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage)

        {

            var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

            responseMessage.Content = "有空再来";

            return responseMessage;

        }

3) 扫描带参数二维码事件

public override IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage)

{

    //通过扫描关注

    var responseMessage = CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "通过扫描关注。";

    return responseMessage;

}

4) 上报地理位置事件

public override IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage)

{

    //这里是微信客户端(通过微信服务器)自动发送过来的位置信息

    var responseMessage = CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "这里写什么都无所谓,比如:上帝爱你!";

    return responseMessage;//这里也可以返回null(需要注意写日志时候null的问题)

}

4. 自定义菜单事件推送

用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报。请注意,第3个到第8个的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。

1) 点击菜单拉取消息时的事件推送

public override IResponseMessageBase OnTextOrEventRequest(RequestMessageText requestMessage)

{

    // 预处理文字或事件类型请求。

    // 这个请求是一个比较特殊的请求,通常用于统一处理来自文字或菜单按钮的同一个执行逻辑,

    // 会在执行OnTextRequest或OnEventRequest之前触发,具有以下一些特征:

    // 1、如果返回null,则继续执行OnTextRequest或OnEventRequest

    // 2、如果返回不为null,则终止执行OnTextRequest或OnEventRequest,返回最终ResponseMessage

    // 3、如果是事件,则会将RequestMessageEvent自动转为RequestMessageText类型,其中RequestMessageText.Content就是RequestMessageEvent.EventKey

 

    if (requestMessage.Content == "OneClick")

    {

        var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

        strongResponseMessage.Content = "您点击了底部按钮。\r\n为了测试微信软件换行bug的应对措施,这里做了一个——\r\n换行";

        return strongResponseMessage;

    }

    return null;//返回null,则继续执行OnTextRequest或OnEventRequest

}

 

public override IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage)

{

    IResponseMessageBase reponseMessage = null;

    //菜单点击,需要跟创建菜单时的Key匹配

    switch (requestMessage.EventKey)

    {

        case "OneClick":

            {

                //这个过程实际已经在OnTextOrEventRequest中完成,这里不会执行到。

                var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Content = "您点击了底部按钮。\r\n为了测试微信软件换行bug的应对措施,这里做了一个——\r\n换行";

            }

            break;

        case "SubClickRoot_Text":

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Content = "您点击了子菜单按钮。";

            }

            break;

        case "SubClickRoot_News":

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageNews>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Articles.Add(new Article()

                {

                    Title = "您点击了子菜单图文按钮",

                    Description = "您点击了子菜单图文按钮,这是一条图文信息。",

                    PicUrl = "http://weixin.senparc.com/Images/qrcode.jpg",

                    Url = "http://weixin.senparc.com"

                });

            }

            break;

        case "SubClickRoot_Music":

            {

                //上传缩略图

                var accessToken = CommonAPIs.AccessTokenContainer.TryGetToken(appId, appSecret);

                var uploadResult = AdvancedAPIs.Media.MediaApi.UploadTemporaryMedia(accessToken, UploadMediaFileType.thumb,

                                                             Server.GetMapPath("~/Images/Logo.jpg"));

                //设置音乐信息

                var strongResponseMessage = CreateResponseMessage<ResponseMessageMusic>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Music.Title = "天籁之音";

                strongResponseMessage.Music.Description = "真的是天籁之音";

                strongResponseMessage.Music.MusicUrl = "http://weixin.senparc.com/Content/music1.mp3";

                strongResponseMessage.Music.HQMusicUrl = "http://weixin.senparc.com/Content/music1.mp3";

                strongResponseMessage.Music.ThumbMediaId = uploadResult.thumb_media_id;

            }

            break;

        case "SubClickRoot_Image":

            {

                //上传图片

                var accessToken = CommonAPIs.AccessTokenContainer.TryGetToken(appId, appSecret);

                var uploadResult = AdvancedAPIs.Media.MediaApi.UploadTemporaryMedia(accessToken, UploadMediaFileType.image,

                                                             Server.GetMapPath("~/Images/Logo.jpg"));

                //设置图片信息

                var strongResponseMessage = CreateResponseMessage<ResponseMessageImage>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Image.MediaId = uploadResult.media_id;

            }

            break;

        case "SubClickRoot_Agent"://代理消息

            {

                //获取返回的XML

                DateTime dt1 = DateTime.Now;

                reponseMessage = MessageAgent.RequestResponseMessage(this, agentUrl, agentToken, RequestDocument.ToString());

                //上面的方法也可以使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString());

 

                DateTime dt2 = DateTime.Now;

 

                if (reponseMessage is ResponseMessageNews)

                {

                    (reponseMessage as ResponseMessageNews)

                        .Articles[0]

                        .Description += string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds);

                }

            }

            break;

        case "Member"://托管代理会员信息

            {

                //原始方法为:MessageAgent.RequestXml(this,agentUrl, agentToken, RequestDocument.ToString());//获取返回的XML

                reponseMessage = this.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString());

            }

            break;

        case "OAuth"://OAuth授权测试

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageNews>();

                strongResponseMessage.Articles.Add(new Article()

                {

                    Title = "OAuth2.0测试",

                    Description = "点击【查看全文】进入授权页面。\r\n注意:此页面仅供测试(是专门的一个临时测试账号的授权,并非Senparc.Weixin.MP SDK官方账号,所以如果授权后出现错误页面数正常情况),测试号随时可能过期。请将此DEMO部署到您自己的服务器上,并使用自己的appid和secret。",

                    Url = "http://weixin.senparc.com/oauth2",

                    PicUrl = "http://weixin.senparc.com/Images/qrcode.jpg"

                });

                reponseMessage = strongResponseMessage;

            }

            break;

        case "Description":

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

                strongResponseMessage.Content = GetWelcomeInfo();

                reponseMessage = strongResponseMessage;

            }

            break;

        case "SubClickRoot_PicPhotoOrAlbum":

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Content = "您点击了【微信拍照】按钮。系统将会弹出拍照或者相册发图。";

            }

            break;

        case "SubClickRoot_ScancodePush":

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

                reponseMessage = strongResponseMessage;

                strongResponseMessage.Content = "您点击了【微信扫码】按钮。";

            }

            break;

        default:

            {

                var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();

                strongResponseMessage.Content = "您点击了按钮,EventKey:" + requestMessage.EventKey;

                reponseMessage = strongResponseMessage;

            }

            break;

    }

 

    return reponseMessage;

}

2) 点击菜单跳转链接时的事件推送

public override IResponseMessageBase OnEvent_ViewRequest(RequestMessageEvent_View requestMessage)

{

   //说明:这条消息只作为接收,下面的responseMessage到达不了客户端,类似OnEvent_UnsubscribeRequest

   var responseMessage = CreateResponseMessage<ResponseMessageText>();

   responseMessage.Content = "您点击了view按钮,将打开网页:" + requestMessage.EventKey;

   return responseMessage;

}

3) 扫码推事件的事件推送

/// <summary>

/// 事件之扫码推事件(scancode_push)

/// </summary>

/// <param name="requestMessage"></param>

/// <returns></returns>

public override IResponseMessageBase OnEvent_ScancodePushRequest(RequestMessageEvent_Scancode_Push requestMessage)

{

    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "事件之扫码推事件";

    return responseMessage;

}

4) 扫码推事件且弹出“消息接收中”提示框的事件推送

/// <summary>

/// 事件之扫码推事件且弹出“消息接收中”提示框(scancode_waitmsg)

/// </summary>

/// <param name="requestMessage"></param>

/// <returns></returns>

public override IResponseMessageBase OnEvent_ScancodeWaitmsgRequest(RequestMessageEvent_Scancode_Waitmsg requestMessage)

{

    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "事件之扫码推事件且弹出“消息接收中”提示框";

    return responseMessage;

}

5) 弹出系统拍照发图的事件推送

/// <summary>

/// 事件之弹出系统拍照发图(pic_sysphoto)

/// 实际测试时发现微信并没有推送RequestMessageEvent_Pic_Sysphoto消息,只能接收到用户在微信中发送的图片消息。

/// </summary>

/// <param name="requestMessage"></param>

/// <returns></returns>

public override IResponseMessageBase OnEvent_PicSysphotoRequest(RequestMessageEvent_Pic_Sysphoto requestMessage)

{

    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "事件之弹出系统拍照发图";

    return responseMessage;

}

6) 弹出拍照或者相册发图的事件推送

/// <summary>

/// 事件之弹出拍照或者相册发图(pic_photo_or_album)

/// </summary>

/// <param name="requestMessage"></param>

/// <returns></returns>

public override IResponseMessageBase OnEvent_PicPhotoOrAlbumRequest(RequestMessageEvent_Pic_Photo_Or_Album requestMessage)

{

   var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

   responseMessage.Content = "事件之弹出拍照或者相册发图";

   return responseMessage;

}

7) 弹出微信相册发图器的事件推送

/// <summary>

/// 事件之弹出微信相册发图器(pic_weixin)

/// </summary>

/// <param name="requestMessage"></param>

/// <returns></returns>

public override IResponseMessageBase OnEvent_PicWeixinRequest(RequestMessageEvent_Pic_Weixin requestMessage)

{

    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "事件之弹出微信相册发图器";

    return responseMessage;

}

8) 弹出地理位置选择器的事件推送

/// <summary>

/// 事件之弹出地理位置选择器(location_select)

/// </summary>

/// <param name="requestMessage"></param>

/// <returns></returns>

public override IResponseMessageBase OnEvent_LocationSelectRequest(RequestMessageEvent_Location_Select requestMessage)

{

    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "事件之弹出地理位置选择器";

    return responseMessage;

}

5. 最后发布到自己的服务器上,可以尝试给公众号发送各种接收事件,验证公众号回复的内容

6. 源码

最后整个程序结构如下:

 

这里的CustomMessageHandler_Events.cs和CustomMessageHandler.cs是同一个类CustomMessageHandler;  一个处理事件,一个处理消息。

源码下载: http://yunpan.cn/cwKCaYahyczTF  访问密码 336e

同样的,使用源码前,要先把配置文件里的参数修改成自己的公众号。

关注事件效果图:

用c#开发微信 系列汇总

用c#开发微信 (4) 基于Senparc.Weixin框架的接收事件推送处理 (源码下载)的更多相关文章

  1. 用c#开发微信(3)基于Senparc.Weixin框架的接收普通消息处理 (源码下载)

    本文讲述使用Senparc.Weixin框架来快速处理各种接收的普通消息.这里的消息指的是传统的微信公众平台消息交互,微信用户向公众号发送消息后,公众号回复消息给微信用户.包括以下7种类型: 1 文本 ...

  2. 微信公众号开发C#系列-7、消息管理-接收事件推送

    1.概述 在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息.其中,某些事件推送在发生后,是允许 ...

  3. 转:C#微信公众号开发之接收事件推送与消息排重的方法

    本文实例讲述了C#微信公众号开发之接收事件推送与消息排重的方法.分享给大家供大家参考.具体分析如下: 微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.这样的话,问题就来了.有这 ...

  4. C#微信公众号开发系列教程五(接收事件推送与消息排重)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  5. C#微信公众号开发系列教程(接收事件推送与消息排重)

    微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.这样的话,问题就来了.有这样一个场景:当用户关注微信账号时,获取当前用户信息,然后将信息写到数据库中.类似于pc端网站的注册.可 ...

  6. PHP开发微信公众号(二)消息接受与推送

    上一篇文章我们知道怎么获取二维码,这样别人就可以扫描二维码来关注我们,但是别人关注后,发送消息,我们怎么进行相关处理? 这里我们就来学习下怎么处理处理这些消息,以及推送消息. 学习之前首先你需要有一个 ...

  7. arcgis api 3.x for js 入门开发系列十七在线天地图、百度地图、高德地图(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  8. Web 开发中很实用的10个效果【附源码下载】

    在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多,但是一时半会又想不起来在哪,所以养成知识整理的习惯是很有必要的.这篇文章给大家推荐10个在 Web 开发中很有用的效果,记 ...

  9. 转:Web 开发中很实用的10个效果【附源码下载】

    原文地址:http://www.cnblogs.com/lhb25/p/10-useful-web-effect.html 在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多 ...

随机推荐

  1. java提高篇(六)-----使用序列化实现对象的拷贝

    我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...

  2. js跨浏览器的事件处理函数

    /* 跨浏览器的事件处理函数 */ var EventUtil = { addHandler : function(element,type,handler){ if(element.addEvent ...

  3. [体感游戏] 1、MPU6050数据采集传输与可视化

    最近在研究体感游戏,到目前为止实现了基于51单片机的MPU6050数据采集.利用蓝牙模块将数据传输到上位机,并利用C#自制串口数据高速采集软件,并且将数据通过自制的折线图绘制模块可视化地展示出来等功能 ...

  4. 由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(二)

    在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP——理论篇中描述了一下ASP.NET新手的三个问题及相关的HTTP协议内容,在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP—— ...

  5. linux bash & profile &bash_profile 小结

    login 方式:: su - oracle 依次 /etc/bash.bashrc———— /home/$user/.bashrc ———— /ect/profile ———— /home/$use ...

  6. Atitit   图像处理 平滑 也称 模糊, 归一化块滤波、高斯滤波、中值滤波、双边滤波)

    Atitit   图像处理 平滑 也称 模糊, 归一化块滤波.高斯滤波.中值滤波.双边滤波) 是一项简单且使用频率很高的图像处理方法 用途 去噪 去雾 各种线性滤波器对图像进行平滑处理,相关OpenC ...

  7. Atitit 图像处理 公共模块 矩阵扫描器

    Atitit 图像处理 公共模块 矩阵扫描器 1.1. 调用说明对矩阵像素遍历处理调用1 2. 矩阵扫描器主题结构1 2.1. 主要说明 从像素点开始填充矩阵1 2.2. 得到模板中心点所对应的图像坐 ...

  8. Gridview转发

    首页 开源项目 问答 动弹 博客 翻译 资讯 专题 城市圈 [ 登录 | 注册 ] 博客专区 > Reya滴水心的博客详情 Asp.net中GridView使用详解(很全,很经典) Reya滴水 ...

  9. JavaScript开发的技巧

    1. 使用===取代==    ==和!=操作符会在需要的情况下自动转换数据类型.但===和!==不会,它们会同时比较值和数据类型,这也使得它们要比==和!=快. "){ //速度慢 } & ...

  10. DOM_02之查找及元素操作

    1.查找之按节点间关系查找周围元素: 2.查找之HTML属性:①按id查找:var elem=document.getElementById("id"):找到一个元素,必须docu ...