MVC下c#对接微信公众平台开发者模式
在ashx文件中进行HttpContext的处理:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Biz.WX;namespace weixinplat {/// <summary>/// WeiXin 的摘要说明/// </summary>public class WeiXin : IHttpHandler{public void ProcessRequest(HttpContext context){try{string postString = string.Empty;//初始化空字符串来转抓到的request请求的bit流context.Response.ContentType = "text/plain";if (context.Request.HttpMethod.ToLower() == "post")//如果从requset的httpmethod方法是post就进行图文等处理 {}else//否则就是get方式,进行校验认证 {AccessToken.Auth();}}catch (Exception ex){throw ex;}}public bool IsReusable{get{return false;}}} }
在专门处理数据的类库Biz中校验:
其中AccessToken类用来处理token:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Configuration;namespace Biz.WeiXin {public class AccessToken{/// <summary>/// 这个函数是初始化配置服务器地址/// </summary>public static void Auth(){string echoStr = HttpContext.Current.Request.QueryString["echoStr"];if (CheckSignature()) //校验签名是否正确 {if (!string.IsNullOrEmpty(echoStr)){HttpContext.Current.Response.Write(echoStr);HttpContext.Current.Response.End();}}}/// <summary>/// 校验微信公众平台签名函数/// </summary>/// <returns></returns>public static bool CheckSignature(){string signature = HttpContext.Current.Request.QueryString["signature"];string timestamp = HttpContext.Current.Request.QueryString["timestamp"];string nonce = HttpContext.Current.Request.QueryString["nonce"];string token = ConfigurationManager.AppSettings["weixin_token"];string[] tmpArr = { token , timestamp, nonce };Array.Sort(tmpArr);string tmpStr = string.Join("", tmpArr);tmpStr = WX.Sha1_Hash(tmpStr);if (tmpStr == signature){return true;}else{returnfalse;}}} }
WX类用来处理哈希算法:
using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks;namespace Biz.WX {public class WX{public static string Sha1_Hash(string str_sha1_in){SHA1 sha1 = new SHA1CryptoServiceProvider();byte[] bytes_sha1_in = UTF8Encoding.Default.GetBytes(str_sha1_in);byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in);string str_sha1_out = BitConverter.ToString(bytes_sha1_out);str_sha1_out = str_sha1_out.Replace("-", "").ToLower();return str_sha1_out;}} }
- 将菜单发布到微信公众平台
在treegrid空间的toolbar工具栏按钮中通过ajax来连接到后台方法:
{id: 'btnRefresh',text: '发布到微信公众平台',iconCls: 'icon-redo',handler: function () {$.ajax({url: "/WxMenu/MenuToWeiXin",data: {},dataType: "json",type: "POST",traditional: true,beforeSend: function () {showProcess(true, "系统提示", "正发布到微信公众平台......");},error: function () {},success: function (result) {showMsg("系统提示", result.Message, false);},complete: function () {showProcess(false);}});}
View Code
连接到后台的MenuToWeiXin方法返回json对象:
public JsonResult MenuToWeiXin(){try{MenuManager.CreateMenu();return Json(new { Success = true, Message = "请求成功" });}catch (Exception ex){return Json(new { Success = false,Message = ex.Message });}}
View Code
其中 MenuManager.CreateMenu()方法就是去将微信菜单对接到微信API上面。如下:
public static void CreateMenu(){NHibernateHelper nhlper = new NHibernateHelper();ISession session = nhlper.GetSession();IEnumerable<WeiXinMenu> kinds = session.Query<WeiXinMenu>();if (kinds.Count() <= 1){throw new Exception("请先配置菜单");}string menu = "";menu += "{\"button\":[";kinds.Where(c => c.ParentId == "10000").Foreach(c => {menu += "{";menu += "\"name\":\"{0}\",".FormartWith(c.MenuName);menu += "\"sub_button\":[";kinds.Where(m=>m.ParentId==c.MenuId).Foreach(m=> {menu += "{";menu += "\"type\":\"{0}\",".FormartWith(m.MenuType);menu += "\"name\":\"{0}\",".FormartWith(m.MenuName);if (m.MenuType == "click"){menu += "\"key\":\"{0}\"".FormartWith(m.MenuKey);}else{menu += "\"url\":\"{0}\"".FormartWith(m.MenuUrl);}menu += "},";});menu = menu.Remove(menu.Length - 1, 1);menu += "]";menu += "},";});menu = menu.Remove(menu.Length - 1, 1);menu += "]";menu += "}";string url = url_menu_create + AccessToken.Weixin_ACCESS_TOKEN;string responsestring = HttpUtils.GetHttprequest(url);JObject result = JsonConvert.DeserializeObject(responsestring) as JObject;string errcode = result["errcode"].ToString();string errmsg = result["errmsg"].ToString();if (errcode != "0"){throw new Exception(Weixin_Errorcode.GetErrormsg(int.Parse(errcode)));}}
View Code
其中url_menu_create是微信给的API接口 private static string url_menu_create = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";
然后将查询到的菜单组装成微信后台需要的json格式。然后调用接口,用post方式的httprequest去访问。可以根据返回的错误代码来知道具体问题是在哪里。
tips:调用微信的很多API接口都需要微信的access_token,所以可以单独写个类来获取:其中AccessToken.Weixin_ACCESS_TOKEN就是获取到微信的access_token:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Configuration; using System.Security.Cryptography; using Business.Extsion; using Newtonsoft.Json; using Newtonsoft.Json.Linq;namespace Business.weixin {public class AccessToken{public static string AppID = ConfigurationManager.AppSettings["weixin_AppID"];public static string AppSecret = ConfigurationManager.AppSettings["weixin_AppSecret"];public static string mAccessToken;public static DateTime GettokenTime;public static int Expires_Period = 7200;//token有效时间,默认2小时/// <summary>/// 正经对接微信公众平台函数。获取echoStr,来返回。/// </summary>public static void Auth(){string echoStr = HttpContext.Current.Request.QueryString["echoStr"];if (CheckSignature()){if (!string.IsNullOrEmpty(echoStr)){HttpContext.Current.Response.Write("echoStr");HttpContext.Current.Response.End();}}}/// <summary>/// 校验函数,微信后台返回的signature和token+timestamp+nonce 对比/// </summary>/// <returns></returns>public static bool CheckSignature(){string signature = HttpContext.Current.Request.QueryString["signature"];string timestamp = HttpContext.Current.Request.QueryString["timestamp"];string nonce = HttpContext.Current.Request.QueryString["nonce"];string token = ConfigurationManager.AppSettings["weixintoken"];string[] tmpArr = { token, timestamp, nonce };Array.Sort(tmpArr);string tmpStr = string.Join("", tmpArr);tmpStr = Sha1_Hash(tmpStr);//通过hash算法得到一个字符串,跟signature对比if (tmpStr == signature){return true;}else{return false;}}public static string Sha1_Hash(string intputstr){SHA1 sha1 =new SHA1CryptoServiceProvider();byte[] byte_in = UTF8Encoding.Default.GetBytes(intputstr);byte[] byte_out = sha1.ComputeHash(byte_in);string outputstr = BitConverter.ToString(byte_out);outputstr = outputstr.Replace("-","").ToLower();return outputstr;}public static string Weixin_ACCESS_TOKEN{get{//如果为空或者过期。则重新获取if (string.IsNullOrEmpty(mAccessToken) || HasExpired()){//获取accesstoken函数mAccessToken = GetAccessToken(AppID, AppSecret);}return mAccessToken;}}/// <summary>/// 判断是不是token过期/// </summary>/// <returns></returns>public static bool HasExpired(){if (GettokenTime != null){if (DateTime.Now > GettokenTime.AddSeconds(7200).AddSeconds(-60)){return true;}}return false;}/// <summary>/// 获取accesstoken函数/// </summary>/// <param name="AppID"></param>/// <param name="AppSecret"></param>/// <returns></returns>public static string GetAccessToken(string AppID,string AppSecret){string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";url = string.Format(url, AppID, AppSecret);string responsestring = HttpUtils.GetHttprequest(url);JObject result = JsonConvert.DeserializeObject(responsestring) as JObject;if (result["access_token"] != null){GettokenTime = DateTime.Now;if (result["expires_in"] != null){Expires_Period = int.Parse(result["expires_in"].ToString());}return result["access_token"].ToString();}else{GettokenTime = DateTime.MinValue;}return null;}} }
View Code
在访问这种api接口的时候都需要主动去访问,所以可以把httprequest请求单独写在一个类HttpUtils中:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks;namespace Business.Extsion {public class HttpUtils{/// <summary>/// 发起一个post类型的http请求/// </summary>/// <param name="url"></param>/// <param name="data"></param>/// <returns></returns>public static string SendHttprequest(string url,string data){return SendPostHttprequest( url, "application/x-www-form-urlencoded", data);}/// <summary>/// 发起一个get模式的http请求/// </summary>/// <returns></returns>public static string GetHttprequest(string url){return SendGetHttprequest(url,"application/x-www-form-urlencoded");}public static string SendPostHttprequest(string url,string contentType, string requestData){WebRequest request = (WebRequest)HttpWebRequest.Create(url);request.Method = "POST";request.ContentType = contentType;byte[] postbytes = Encoding.UTF8.GetBytes(requestData);request.ContentLength = postbytes.Length;using (Stream outstream = request.GetRequestStream()){outstream.Write(postbytes, 0, postbytes.Length);}string result = string.Empty;using (WebResponse response = request.GetResponse()){if (response !=null){using (Stream getstream = response.GetResponseStream()){using (StreamReader reader = new StreamReader(getstream,Encoding.UTF8)){result = reader.ReadToEnd();}}}}return result;}public static string SendGetHttprequest(string url ,string contenType){WebRequest request = (WebRequest)HttpWebRequest.Create(url);request.Method = "GET";request.ContentType = contenType;string result = string.Empty;using (WebResponse response = request.GetResponse()){if (response != null){using (Stream resstream = response.GetResponseStream()){using (StreamReader reader = new StreamReader(resstream,Encoding.UTF8) ){result = reader.ReadToEnd();}}}}return result;}} }
View Code
- 编辑新增菜单
通过控制器返回视图:
public ActionResult MenuEdit(int id){NHibernateHelper nhlper = new NHibernateHelper();ISession session = nhlper.GetSession();WeiXinMenu model = session.Get<WeiXinMenu>(id);if (model == null){model = new WeiXinMenu();model.IsEnable = "1";model.CreateTime = DateTime.Now;}return View(model);}
View Code
控制器动作跟着返回查询到的model在视图上显示:
@model Domain.OrmLib.Entity.WeiXinMenu @{ViewBag.Title = "MenuEdit";Layout = "~/Views/Shared/_Form.cshtml"; }@section header {}@section body{@using (Html.BeginForm("MenuSaveOrUpdate", "WeiXin", FormMethod.Post, new { id = "dataForm" })){<table class="datalistDaily" cellpadding="5" style="font-size:12px;margin-top:10px;margin-left:10px;"><tr><td style="text-align:right;">菜单编码:</td><td><input class="easyui-textbox" id="MenuId" name="MenuId"style="width:300px;" data-options="required:true" value="@Model.MenuId" /></td></tr><tr><td style="text-align:right;">菜单名字:</td><td><input class="easyui-textbox" id="MenuName" name="MenuName"style="width:300px;" data-options="required:true" value="@Model.MenuName" /></td></tr><tr><td style="text-align:right;">动作类型:</td><td><select id="MenuType" name="MenuType" class="easyui-combobox" style="width:300px;"><option selected="selected" value="view">跳转URL</option><option value="click">点击推事件</option><option value="scancode_push">扫码推事件</option><option value="scancode_waitmsg">扫码推事件且弹出(消息接收中)提示框</option><option value="pic_sysphoto">弹出系统拍照发图</option><option value="pic_photo_or_album">弹出拍照或者相册发图</option><option value="pic_weixin">弹出微信相册发图器</option><option value="location_select">弹出地理位置选择器</option><option value="media_id">下发消息(除文本消息)</option><option value="view_limited">跳转图文消息URL</option></select></td></tr><tr><td style="text-align:right;">菜单Url:</td><td><input class="easyui-textbox" id="MenuUrl" name="MenuUrl"style="width:300px;" value="@Model.MenuUrl" /></td></tr><tr><td style="text-align:right;">菜单Key:</td><td><input class="easyui-textbox" id="MenuKey" name="MenuKey"style="width:300px;" value="@Model.MenuKey" /></td></tr><tr><td style="text-align:right;">菜单排序:</td><td><input class="easyui-textbox" id="OrderBy" name="OrderBy" data-options="required:true"style="width:300px;" value="@Model.OrderBy" /></td></tr><tr><td style="text-align:right;">菜单状态:</td><td><select id="IsEnable" name="IsEnable" class="easyui-combobox" style="width:300px;"><option selected="selected" value="1">启用菜单</option><option value="0">禁用菜单</option></select></td></tr><tr><td style="text-align:right;">上级菜单:</td><td><input class="easyui-combotree" name="ParentId" id="ParentId" style="width:300px;" /></td></tr><tr><td colspan="2" align="center"></td></tr><tr><td colspan="2" align="center">@Html.HiddenFor(model => model.Id)@Html.HiddenFor(model => model.UserNum)@Html.HiddenFor(model => model.UserName)@Html.HiddenFor(model => model.CreateTime)<a icon="icon-ok" class="easyui-linkbutton" οnclick="save()">存盘</a></td></tr></table>}}@section scripts { <script src="~/Content/oa/scripts/xlayout.js"></script> <script type="text/javascript">$(function () {$('#ParentId').combotree({url: "/WxMenu/MenuTree",required: true,multiple: false,lines: true,queryParams: { ids: '@Model.ParentId' },onLoadSuccess: function () {$('#ParentId').combotree('setValue', '@Model.ParentId');}});$('#MenuType').combobox('setValue', '@Model.MenuType');$('#IsEnable').combobox('setValue', '@Model.IsEnable');})function save() {alert(2212);var dataForm = $("#dataForm").form('validate');if (!dataForm) return;showProcess(true, "系统提示", "正在存盘中......");$.ajax({url: "/WxMenu/MenuSaveOrUpdate",data: $("#dataForm").serialize(),dataType: "json",type: "POST",traditional: true,success: function (result) {showProcess(false);if (result.Success) {var sys_main = $(self.top.document).find("#sys_main").get(0).contentWindow;sys_main.radWindowCallBackFn();var url = document.URL;url = url.replace("http://" + window.location.host, "");url = url.replace(/\//g, "_"); sys_main.CloseWindow(url);} else {showMsg("系统提示", result.Message, false);}}});return false;}</script>}
View Code
通过ajax在后台进行saveorupdate
转载于:https://www.cnblogs.com/jackcheblog/p/6864309.html
MVC下c#对接微信公众平台开发者模式相关推荐
- 微信公众号开发者自动回复php,微信公众平台开发者模式的启用并自动回复
这篇文章介绍的内容是关于微信公众平台开发者模式的启用并自动回复,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 首先,什么是开发者模式? 开发者模式,就是先验证你的服务器地址,验证完成之 ...
- 微信公众平台开发者模式(1)JAVA版接入
接入必须的参数 URL服务器地址用于接受微信消息和事件(http://--.aliapp.com/servlet/MyServlet servlet/MyServlet为web.xml中你配置的url ...
- 微信公众平台开发者配置
目录 第一部分 启用开发者配置 (1) 登录微信公众平台 (2)配置IP 白名单 (3)启用开发者配置 (4)具体的代码调用部分 第二部分 接收事件推送 (1)接口 (2) 业务逻辑类 (3)Mess ...
- Java对接微信公众平台详解
Java对接微信公众平台详解 1.公众平台概述 1.1 公众平台概述 1.2 入门指引 2.对接流程 2.1 接入概述 2.2 填写服务器配置 2.3 接口域名说明 2.4 获取Access toke ...
- php网站怎么对接微信群,PHP对接微信公众平台消息接口开发流程教程
PHP(外文名:PHP: Hypertext Preprocessor,中文名:"超文本预处理器")是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使 ...
- php对接微信提醒,PHP对接微信公众平台消息接口开发流程教程
PHP对接微信公众平台消息接口开发流程教程 发布于 2015-02-15 08:54:13 | 157 次阅读 | 评论: 1 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hyperte ...
- php微信公众号怎么开发_PHP对接微信公众平台消息接口开发流程详解及实例
这篇文章主要介绍了PHP对接微信公众平台消息接口开发流程,如何使用PHP版接口操作公众平台消息,需要的朋友可以参考下 一.写好接口程序 在你的服务器上上传好一个接口程序文件内容如下: 代码如下:< ...
- 微信|公众平台开发者文档
微信|公众平台开发者文档 http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html 爱父母项目(提示用户名,密码在项目文 ...
- [转]简单几步成为微信公众平台开发者 - 杨栋
简单几步成为微信公众平台开发者 - 杨栋 时间 2013-09-29 16:36:00 博客园-原创精华区原文 http://www.cnblogs.com/yangdong/p/3345890. ...
最新文章
- 【lidar】3D目标检测PointPillars:论文解读、代码解读、部署实现(1)
- oracle 10 升级补丁
- sqlbulkcopy是覆盖式更新吗_React 328道最全面试题(持续更新)
- C# viewstate
- 关于工厂模式---转发
- 多标签文本分类数据集_标签感知的文档表示用于多标签文本分类(EMNLP 2019)...
- 【机器学习】feature_importances_ 参数源码解析
- MySQL流浪记(五)—— MySQL中常见函数的使用(笔记)
- 程序员夏天格子衫,冬天穿什么?
- 保卫Google!刻不容缓
- android布局自适应小示例(用户反馈界面)
- 寻找最小term,自制面试题
- 区间最值操作与历史最值问题(二)
- quartus中与modelsim进行联合仿真出现错误error:(vopt-13130)failed to find design unit****
- 计算机关机打不开,笔记本电脑强制关机打不开了怎么办
- android读取assets下的.json文件,并且转化为实体类
- 『统计学』常用的数据分析方法都在这了!Part.2
- iOS开发 : Navigation Bar的简单设置
- 【精品软件】WeGo(微博PPC客户端) Release Note (更新至v1.05 Build20110117)
- FCFS,SJF以及PSA进程调度算法效率的比较
热门文章
- jvm中方法区和常量池详解_JVM——内存区域:运行时数据区域详解
- antd如何获取表单的值_JavaScript多个表单序列化获取值
- 3d 根据弧长算角度_3D立体画,让你身临其境
- 《假设的世界-一切不能想当然》笔记
- 如何按距离排序 php,php做附近的人,根据距离由近到远进行排序
- AS:Flash AS3中获取浏览器信息及URL相关参数(并非swf url地址)
- mapreduce阶段出现pending的原因及解决
- java语言中实现键盘输入_Java程序设计中的键盘输入数据的方法分析
- 前端证券项目_非科班二本前端大厂面试的心路历程和总结(腾讯、头条、阿里、京东)...
- zabbix 监控项自动发现过滤_Zabbix使用javascript+jsonpath预处理动态生成监控项