企业微信开发者,提供的第三方接口DEMO。

 

企业号需要下载微信提供的加解密文件,里面加解密就是调用下载的cs帮助类。

顺便提示下:接口的地址好像不可以MVC模式的地址,我尝试的时候接收不到参数。

如:http://xxxx/Control/Action  这个地址可以做验证URL,但是接收不到数据,微信直接报错

最后只能改成带后缀的:http://xxxx/xxxx/xx.ashx  或者xx.aspx

 

开发思路:一个接口里面区分get和post请求,get请求是绑定到企业号的时候用,post是微信接收消息时候用

get:获取微信参数,拿到之后实现加密对比,然后返回一个字符参数,代表验证成功

post:获取微信给的XML,然后再返回一个XML字符串就行。不做任何消息回复就给他返回success

 

返回代码用这个就行:

HttpContext.Current.Response.Write(XML);
HttpContext.Current.Response.End();

企业微信参考资料:

验证URL

​https://jingyan.baidu.com/article/154b46319f1c6e68ca8f4180.html ​

接收消息和回复

​https://jingyan.baidu.com/article/39810a233e9d5ef637fda66b.html​

公众号的参考:

验证URL

​https://jingyan.baidu.com/article/8cdccae9a6ca9f715413cdf3.html​

接收消息和回复

​https://jingyan.baidu.com/article/f3ad7d0fa077ce49c3345be0.html​

using Message.Web.Api.Open.Model;
using Message.Web.Api.Open.Util;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.SessionState;
using System.Xml;

namespace Message.Web.Api.Open
{
/// <summary>
/// API 的摘要说明
/// </summary>
public class API : IHttpHandler, IRequiresSessionState
{
private static string post_data = "";

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
#region 获取调试日志
if (context.Request.QueryString["log"] == "1")
{
context.Response.Write(post_data);
context.Response.End();
}
#endregion
if (context.Request.HttpMethod.ToLower() == "post")
{
//接收消息
ReceiveXml();
}
else
{
//验证配置,微信第一次验证走GET斤这里
CheckWechat();
}
}
private void ReceiveXml()
{
Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
byte[] requestByte = new byte[requestStream.Length];
requestStream.Read(requestByte, 0, (int)requestStream.Length);
string requestStr = Encoding.UTF8.GetString(requestByte);
post_data += "得到数据:" + requestStr + "<br/>";
string corpId = ConfigurationManager.AppSettings["WXCorpId"];
string access_token = ConfigurationManager.AppSettings["WXToken"];
string encodingAESKey = ConfigurationManager.AppSettings["WXEncodingAESKey"];

string signature = HttpContext.Current.Request.QueryString["msg_signature"].ToString();
string timestamp = HttpContext.Current.Request.QueryString["timestamp"].ToString();
string nonce = HttpContext.Current.Request.QueryString["nonce"].ToString();

Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(access_token, encodingAESKey, corpId);
//解密后的requestStr
int error = wxcpt.DecryptMsg(signature, timestamp, nonce, requestStr, ref requestStr);
post_data += "解密结果:" + error + "<br/>";
post_data += "解密数据:" + requestStr + "<br/>";
WxXmlModel WxXmlModel = new WxXmlModel();
#region 封装请求类
//封装请求类
XmlDocument requestDocXml = new XmlDocument();
requestDocXml.LoadXml(requestStr);
XmlElement rootElement = requestDocXml.DocumentElement;
WxXmlModel.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
WxXmlModel.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
WxXmlModel.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
WxXmlModel.MsgType = rootElement.SelectSingleNode("MsgType").InnerText;
switch (WxXmlModel.MsgType)
{
case "text"://文本
WxXmlModel.Content = rootElement.SelectSingleNode("Content").InnerText;
break;
case "event"://事件
WxXmlModel.Event = rootElement.SelectSingleNode("Event").InnerText;
//按钮点击事件
if (WxXmlModel.Event == "taskcard_click")
{
WxXmlModel.EventKey = rootElement.SelectSingleNode("EventKey").InnerText;
WxXmlModel.TaskId = rootElement.SelectSingleNode("TaskId").InnerText;
WxXmlModel.AgentId = rootElement.SelectSingleNode("AgentId").InnerText;
}
break;
default:
break;
}
#endregion
//返回
ResponseXML(WxXmlModel, wxcpt, timestamp, nonce);

}
private void ResponseXML(WxXmlModel WxXmlModel, Tencent.WXBizMsgCrypt wxcpt, string timestamp, string nonce)
{
string XML = "success";
#region 逻辑处理
switch (WxXmlModel.MsgType)
{
case "text"://文本回复
//XML = GetText(WxXmlModel.ToUserName, WxXmlModel.FromUserName, WxXmlModel.Content);
break;
case "event"://文本回复
if (WxXmlModel.Event == "taskcard_click")
{

}
break;
default://默认回复
break;
}
#endregion

post_data += "返回数据:" + XML + "<br/>";

int error = wxcpt.EncryptMsg(XML, timestamp, nonce, ref XML);
post_data += "返回结果:" + error + "<br/>";
//把结果返回给微信
HttpContext.Current.Response.Write(XML);
HttpContext.Current.Response.End();
}

public static string GetText(string FromUserName, string ToUserName, string Content)
{
string XML = ReText(FromUserName, ToUserName, Content);
//switch (Content)
//{
// case "关键字":
// XML = ReText(FromUserName, ToUserName, "关键词回复测试");
// break;
// case "单图文":
// XML = ReArticle(FromUserName, ToUserName, "测试标题", "测试详情——百度搜索链接", "", "http://www.baidu.com");
// break;
// default:
// XML = ReText(FromUserName, ToUserName, "无对应关键字");
// break;
//}
return XML;
}
///
/// 回复文本
///
/// 发送给谁(openid)
/// 来自谁(公众账号ID)
/// 回复类型文本
/// 拼凑的XML
public static string ReText(string FromUserName, string ToUserName, string Content)
{
string xml = "<xml>";
xml += "<ToUserName><![CDATA[" + ToUserName + "]]></ToUserName>";
xml += "<FromUserName><![CDATA[" + FromUserName + "]]></FromUserName>";
xml += "<CreateTime>" + GetCurrentTimeUnix() + "</CreateTime>";
xml += "<MsgType><![CDATA[text]]></MsgType>";
xml += "<Content><![CDATA[" + Content + "]]></Content>";
xml += "</xml>";
//"" + Content + "0";//回复内容 FuncFlag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用
return xml;
}
public static string GetCurrentTimeUnix()
{
TimeSpan cha = (DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)));
long t = (long)cha.TotalSeconds;
return t.ToString();
}
///
/// 返回随机数表示验证成功
///
private void CheckWechat()
{
if (string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["echoStr"]))
{
HttpContext.Current.Response.Write("消息并非来自微信");
HttpContext.Current.Response.End();
}
string echoStr = "";
if (CheckSignature(ref echoStr))
{
HttpContext.Current.Response.Write(echoStr);
HttpContext.Current.Response.End();
}
}

///
/// 验证微信签名
///
///
/// * 将token、timestamp、nonce三个参数进行字典序排序
/// * 将三个参数字符串拼接成一个字符串进行sha1加密
/// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。
private bool CheckSignature(ref string echoStr)
{
string corpId = ConfigurationManager.AppSettings["WXCorpId"];
string access_token = ConfigurationManager.AppSettings["WXToken"];
string encodingAESKey = ConfigurationManager.AppSettings["WXEncodingAESKey"];

string signature = HttpContext.Current.Request.QueryString["msg_signature"].ToString();
string timestamp = HttpContext.Current.Request.QueryString["timestamp"].ToString();
string nonce = HttpContext.Current.Request.QueryString["nonce"].ToString();
string echostr = HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request.QueryString["echostr"].ToString());

Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(access_token, encodingAESKey, corpId);
//解析之后的明文
echoStr = "";
int ret = wxcpt.VerifyURL(signature, timestamp, nonce, echostr, ref echoStr);
return ret == 0;
}

private static string SHA1Hash(string value)
{
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] bytes_sha1_in = UTF8Encoding.Default.GetBytes(value);
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("-", "");
return str_sha1_out;
}
public bool IsReusable
{
get
{
return false;
}
}
}
}