public ActionResult Callback() { var code = Request.QueryString.Get("code"); if (string.IsNullOrEmpty(code))//没有code表示授权失败 { return(RedirectToAction("Failed", "OAuth")); } var state = Request.QueryString.Get("state"); var cache_status = System.Web.HttpContext.Current.Cache.Get(state); var redirect_url = cache_status == null ? "/" : cache_status.ToString();//没有获取到state,就跳转到首页 var scope = WeixinConfig.OauthScope; var access_token_scope = ""; double expires_in = 0; var access_token = ""; var openId = ""; var token = OAuth2API.GetAccessToken(code, WeixinConfig.AppID, WeixinConfig.AppSecret); dynamic userinfo; if (scope == "snsapi_userinfo") { var refreshAccess_token = OAuth2API.RefreshAccess_token(token.refresh_token, WeixinConfig.AppID); access_token = refreshAccess_token.access_token;//通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。 openId = refreshAccess_token.openid; access_token_scope = refreshAccess_token.scope; expires_in = refreshAccess_token.expires_in; userinfo = OAuth2API.GetUserInfo(access_token, openId);//snsapi_userinfo,可以用户在未关注公众号的情况下获取用户基本信息 } else { access_token = WeixinConfig.TokenHelper.GetToken();//基础支持中的access_token openId = token.openid; expires_in = token.expires_in; //TODO: 如果用户已经关注,可以用openid,获取用户信息。 userinfo = UserAdminAPI.GetInfo(access_token, openId);//如果本地已经存储了用户基本信息,建议在本地获取。 } //写入session //写入cookies AuthorizationManager.SetTicket(true, 1, openId, userinfo.nickname); Thread.Sleep(500);//暂停半秒钟,以等待IOS设置Cookies的延迟 LogWriter.Default.WriteInfo(string.Format("OAuth success: identity: {0} , name: {1} , redirect_rul:{2} , expires_in: {3}s ", openId, userinfo.nickname, redirect_url, expires_in)); return(new RedirectResult(redirect_url, true)); }
/// <summary> /// 说明:带TODO字眼的代码段,需要开发者自行按照自己的业务逻辑实现 /// </summary> /// <param name="message"></param> /// <returns>已经打包成xml的用于回复用户的消息包</returns> public string Execute(WeixinMessage message) { var result = ""; var openId = message.Body.FromUserName.Value; var myUserName = message.Body.ToUserName.Value; //这里需要调用TokenHelper获取Token的,省略了。 #region 记录接收信息 var receiveMessage = new WeiXinReceiveMessage() { ToUserName = myUserName, FromUserName = openId, CreateDate = DateTime.Now, CreateTime = message.Body.CreateTime.Value, MsgType = message.Body.MsgType.Value, MsgId = message.Type == WeixinMessageType.Event ? "" : message.Body.MsgId.Value //事件没有这个参数 }; #endregion switch (message.Type) { case WeixinMessageType.Text: //文字消息 #region 文字消息 string userMessage = message.Body.Content.Value; receiveMessage.Content = userMessage; //用于记录接收信息 var reply = _replyMessage.GetMessage(userMessage, myUserName); //查找回复信息表 result = Repay(reply, openId, myUserName); #endregion break; case WeixinMessageType.Image: //图片消息 #region 图片消息 string imageUrl = message.Body.PicUrl.Value; //图片地址 string mediaId = message.Body.MediaId.Value; //mediaId receiveMessage.PicUrl = imageUrl; receiveMessage.MediaId = mediaId; #endregion break; case WeixinMessageType.Video: //视频消息 #region 视频消息 { var media_id = message.Body.MediaId.Value.ToString(); var thumb_media_id = message.Body.ThumbMediaId.Value.ToString(); receiveMessage.MediaId = media_id; receiveMessage.ThumbMediaId = thumb_media_id; } #endregion break; case WeixinMessageType.Voice: //语音消息 #region 语音消息 { var media_id = message.Body.MediaId.Value.ToString(); var format = message.Body.Format.Value.ToString(); receiveMessage.MediaId = media_id; receiveMessage.Format = format; } #endregion break; case WeixinMessageType.Location: //地理位置消息 #region 地理位置消息 { var location_X = message.Body.Location_X.Value.ToString(); var location_Y = message.Body.Location_Y.Value.ToString(); var scale = message.Body.Scale.Value.ToString(); var Label = message.Body.Label.Value.ToString(); receiveMessage.Location_X = location_X; receiveMessage.Location_Y = location_Y; receiveMessage.Scale = scale; receiveMessage.Label = Label; } #endregion break; case WeixinMessageType.Link: //链接消息 #region 链接消息 { var title = message.Body.Title.Value.ToString(); var description = message.Body.Description.Value.ToString(); var url = message.Body.Url.Value.ToString(); receiveMessage.Title = title; receiveMessage.Description = description; receiveMessage.Url = url; } #endregion break; case WeixinMessageType.Event: #region 事件 string eventType = message.Body.Event.Value.ToLower(); string eventKey = string.Empty; try { eventKey = message.Body.EventKey.Value; } catch { } receiveMessage.EventType = eventType; receiveMessage.EventKey = eventKey; switch (eventType) { case "subscribe": //用户未关注时,进行关注后的事件推送 #region 首次关注 //TODO: 获取用户基本信息后,将用户信息存储在本地。 var weixinInfo = UserAdminAPI.GetInfo(AccountToken(), openId); //注意:订阅号没有此权限 var userinfoDto = JsonConvert.DeserializeObject <WeiXinUserDto>(JsonConvert.SerializeObject(weixinInfo)); var userinfo = EntityMapper.Map <WeiXinUserDto, WeiXinUser>(userinfoDto); userinfo.createtime = DateTime.Now; if (_userTask.GetByOpenId(openId) == null) { _userTask.AddUser(userinfo); //保存用户关注数据 } reply = _replyMessage.GetMessageByReplayType(eventType, eventKey, myUserName); //查找回复信息表 result = Repay(reply, openId, myUserName); #endregion break; case "unsubscribe": //取消关注 #region 取消关注 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, "欢迎再来"); #endregion break; case "scan": // 用户已关注时的事件推送 #region 已关注扫码事件 if (!string.IsNullOrEmpty(eventKey)) { var qrscene = eventKey.Replace("qrscene_", ""); //此为场景二维码的场景值 result = ReplayPassiveMessageAPI.RepayNews(openId, myUserName, new WeixinNews { title = "欢迎使用,场景值:" + qrscene, description = "欢迎使用,场景值:" + qrscene, picurl = string.Format("{0}/ad.jpg", domain), url = domain }); } else { result = ReplayPassiveMessageAPI.RepayNews(openId, myUserName, new WeixinNews { title = "欢迎使用", description = "欢迎订阅,点击此消息查看在线demo", picurl = string.Format("{0}/ad.jpg", domain), url = domain }); } #endregion break; case "masssendjobfinish": //事件推送群发结果, #region 事件推送群发结果 { var msgId = message.Body.MsgID.Value; var msgStatus = message.Body.Status.Value; //“send success”或“send fail”或“err(num)” //send success时,也有可能因用户拒收公众号的消息、系统错误等原因造成少量用户接收失败。 //err(num)是审核失败的具体原因,可能的情况如下:err(10001)涉嫌广告, err(20001)涉嫌政治, err(20004)涉嫌社会, err(20002)涉嫌色情, err(20006)涉嫌违法犯罪, //err(20008)涉嫌欺诈, err(20013)涉嫌版权, err(22000)涉嫌互推(互相宣传), err(21000)涉嫌其他 var totalCount = message.Body.TotalCount.Value; //group_id下粉丝数;或者openid_list中的粉丝数 var filterCount = message.Body.FilterCount.Value; //过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,FilterCount = SentCount + ErrorCount var sentCount = message.Body.SentCount.Value; //发送成功的粉丝数 var errorCount = message.Body.FilterCount.Value; //发送失败的粉丝数 //TODO:开发者自己的处理逻辑,这里用log4net记录日志 // LogWriter.Default.WriteInfo(string.Format("mass send job finishe,msgId:{0},msgStatus:{1},totalCount:{2},filterCount:{3},sentCount:{4},errorCount:{5}", msgId, msgStatus, totalCount, filterCount, sentCount, errorCount)); } #endregion break; case "templatesendjobfinish": //模版消息结果, #region 模版消息结果 { var msgId = message.Body.MsgID.Value; var msgStatus = message.Body.Status.Value; //发送状态为成功: success; 用户拒绝接收:failed:user block; 发送状态为发送失败(非用户拒绝):failed: system failed //TODO:开发者自己的处理逻辑,这里用log4net记录日志 //LogWriter.Default.WriteInfo(string.Format("template send job finish,msgId:{0},msgStatus:{1}", msgId, msgStatus)); } #endregion break; case "location": //上报地理位置事件 #region 报地理位置事件 var lat = message.Body.Latitude.Value.ToString(); var lng = message.Body.Longitude.Value.ToString(); var pcn = message.Body.Precision.Value.ToString(); //TODO:在此处将经纬度记录在数据库,这里用log4net记录日志 // LogWriter.Default.WriteInfo(string.Format("openid:{0} ,location,lat:{1},lng:{2},pcn:{3}", openId, lat, lng, pcn)); #endregion break; case "voice": //语音消息 #region 语音消息 //A:已开通语音识别权限的公众号 var userVoice = message.Body.Recognition.Value; //用户语音消息文字 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, "您说:" + userVoice); //B:未开通语音识别权限的公众号 var userVoiceMediaId = message.Body.MediaId.Value; //media_id //TODO:调用自定义的语音识别程序识别用户语义 #endregion break; case "image": //图片消息 #region 图片消息 var userImage = message.Body.PicUrl.Value; //用户语音消息文字 result = ReplayPassiveMessageAPI.RepayNews(openId, myUserName, new WeixinNews { title = "您刚才发送了图片消息", picurl = string.Format("{0}/Images/ad.jpg", domain), description = "点击查看图片", url = userImage }); #endregion break; case "click": //自定义菜单事件 #region 自定义菜单事件 { reply = _replyMessage.GetMessageByReplayType(eventType, eventKey, myUserName); //查找回复信息表 result = Repay(reply, openId, myUserName); } #endregion break; case "view": //点击菜单跳转链接时的事件推送 #region 点击菜单跳转链接时的事件推送 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("您将跳转至:{0}", eventKey)); #endregion break; #region 仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送 case "scancode_push": //扫码推事件的事件推送 { var scanType = message.Body.ScanCodeInfo.ScanType.Value; //扫描类型,一般是qrcode var scanResult = message.Body.ScanCodeInfo.ScanResult.Value; //扫描结果,即二维码对应的字符串信息 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("您扫描了二维码,scanType:{0},scanResult:{1},EventKey:{2}", scanType, scanResult, eventKey)); } break; case "scancode_waitmsg": //扫码推事件且弹出“消息接收中”提示框的事件推送 { var scanType = message.Body.ScanCodeInfo.ScanType.Value; //扫描类型,一般是qrcode var scanResult = message.Body.ScanCodeInfo.ScanResult.Value; //扫描结果,即二维码对应的字符串信息 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("您扫描了二维码,scanType:{0},scanResult:{1},EventKey:{2}", scanType, scanResult, eventKey)); } break; case "pic_sysphoto": //弹出系统拍照发图的事件推送 { var count = message.Body.SendPicsInfo.Count; //发送的图片数量 var picList = message.Body.PicList; //发送的图片信息 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("弹出系统拍照发图,count:{0},EventKey:{1}", count, eventKey)); } break; case "pic_photo_or_album": //弹出拍照或者相册发图的事件推送 { var count = message.Body.SendPicsInfo.Count.Value; //发送的图片数量 var picList = message.Body.PicList.Value; //发送的图片信息 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("弹出拍照或者相册发图,count:{0},EventKey:{1}", count, eventKey)); } break; case "pic_weixin": //弹出微信相册发图器的事件推送 { var count = message.Body.SendPicsInfo.Count.Value; //发送的图片数量 var picList = message.Body.PicList.Value; //发送的图片信息 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("弹出微信相册发图器,count:{0},EventKey:{1}", count, eventKey)); } break; case "location_select": //弹出地理位置选择器的事件推送 { var location_X = message.Body.SendLocationInfo.Location_X.Value; //X坐标信息 var location_Y = message.Body.SendLocationInfo.Location_Y.Value; //Y坐标信息 var scale = message.Body.SendLocationInfo.Scale.Value; //精度,可理解为精度或者比例尺、越精细的话 scale越高 var label = message.Body.SendLocationInfo.Label.Value; //地理位置的字符串信息 var poiname = message.Body.SendLocationInfo.Poiname.Value; //朋友圈POI的名字,可能为空 result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("弹出地理位置选择器,location_X:{0},location_Y:{1},scale:{2},label:{3},poiname:{4},eventKey:{5}", location_X, location_Y, scale, label, poiname, eventKey)); } break; case "card_pass_check": //生成的卡券通过审核时,微信会把这个事件推送到开发者填写的URL。 { var cardid = message.Body.CardId.Value; //CardId result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("您的卡券已经通过审核")); } break; case "card_not_pass_check": //生成的卡券未通过审核时,微信会把这个事件推送到开发者填写的URL。 { var cardid = message.Body.CardId.Value; //CardId } break; case "user_get_card": //用户在领取卡券时,微信会把这个事件推送到开发者填写的URL。 { var cardid = message.Body.CardId.Value; //CardId var isGiveByFriend = message.Body.IsGiveByFriend.Value; //是否为转赠,1代表是,0代表否。 var fromUserName = message.Body.FromUserName.Value; //领券方帐号(一个OpenID) var friendUserName = message.Body.FriendUserName.Value; //赠送方账号(一个OpenID),"IsGiveByFriend”为1时填写该参数。 var userCardCode = message.Body.UserCardCode.Value; //code序列号。自定义code及非自定义code的卡券被领取后都支持事件推送。 var outerId = message.Body.OuterId.Value; //领取场景值,用于领取渠道数据统计。可在生成二维码接口及添加JSAPI接口中自定义该字段的整型值。 } break; case "user_del_card": //用户在删除卡券时,微信会把这个事件推送到开发者填写的URL { var cardid = message.Body.CardId.Value; //CardId var userCardCode = message.Body.UserCardCode.Value; //商户自定义code值。非自定code推送为空 } break; case "merchant_order": //微信小店:订单付款通知:在用户在微信中付款成功后,微信服务器会将订单付款通知推送到开发者在公众平台网站中设置的回调URL(在开发模式中设置)中,如未设置回调URL,则获取不到该事件推送。 { var orderId = message.Body.OrderId.Value; //CardId var orderStatus = message.Body.OrderStatus.Value; //OrderStatus var productId = message.Body.ProductId.Value; //ProductId var skuInfo = message.Body.SkuInfo.Value; //SkuInfo } break; #endregion } #endregion break; default: result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, string.Format("未处理消息类型:{0}", message.Type)); break; } _receiveMessage.AddMessage(receiveMessage); return(result); }
public ActionResult DefaultAuthorize(string code, string state) { try { if (state == "wanlixin") { var scope = WeixinConfig.OauthScope; double expires_in = 0; var access_token = ""; var openId = ""; var token = OAuth2API.GetAccessToken(code, WeixinConfig.AppID, WeixinConfig.AppSecret); dynamic userinfo; //access_token = WeixinConfig.TokenHelper.GetToken();//基础支持中的access_token access_token = AccessTokenContainer.TryGetAccessToken(WeixinConfig.AppID, WeixinConfig.AppSecret, true); openId = token.openid; expires_in = token.expires_in; //TODO: 如果用户已经关注,可以用openid,获取用户信息。 userinfo = UserAdminAPI.GetInfo(access_token, openId);//如果本地已经存储了用户基本信息,建议在本地获取。 Tools.MessBox(string.Format("时间:{0},描述:{1}", DateTime.Now, userinfo), "//Log//Weixin//DefaultAuthorize//userinfo//"); //通过api接口,根据openid查找,如果openid已经保存,跳转到”会员积分查询“页面,否则跳转到”输入手机号码页面“ Tools.MessBox("openId:" + openId); var usermodel = WebUtils.Get2 <CustomerNewSelect>(WebConfig.ApiBaseUrl + "WlxApi/GetCustomerNewBySql", openId); //Tools.MessBox("usermodel:"+ usermodel.c_num); if (usermodel != null) { if (!string.IsNullOrEmpty(usermodel.c_num))//c_openid已经更新过 { Customer customer = new Customer(); customer.Phone = usermodel.c_num; Session["Customer"] = customer; h_CustomerNew h_CustomerNew = new h_CustomerNew(); h_CustomerNew.c_num = usermodel.c_num; h_CustomerNew.c_Name = usermodel.c_Name; h_CustomerNew.c_Identity = usermodel.c_Identity; Session["h_CustomerNew"] = h_CustomerNew; return(RedirectToAction("Member", "Home")); } } else { //插入微信信息 LoginService _loginservice = new LoginService(); Customer customer = _loginservice.CustomerLogin(userinfo.nickname, userinfo.openid, "", "", userinfo.headimgurl, Convert.ToInt32(userinfo.sex), userinfo.province, userinfo.city); if (customer != null) { Session["Customer"] = customer; } return(RedirectToAction("Index", "Home")); } } return(Content("验证失败4")); } catch (Exception ex) { string st = string.Format("时间:{0},描述:{1}", DateTime.Now, ex.ToString()); Tools.MessBox(st, "//Log//Weixin//"); return(Redirect("/error/index")); } }