WxHandler.ashx
using System;
using System.Text;
using System.Web;
using System.Web.Security;
using Service;
namespace ShareServer.Handler
{
/// <summary>
/// 微信業務邏輯處理
/// </summary>
public class WxHandler : IHttpHandler
{
private readonly WxService service = new WxService();
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/json";
var type = context.Request["type"];
switch (type)
{
case "share":
Share(context);
break;
case "auth":
Auth(context);
break;
case "openid":
OpenId(context);
break;
default:
break;
}
}
public bool IsReusable
{
get { return false; }
}
/// <summary>
/// 微信分享
/// </summary>
/// <param name="context"></param>
private void Share(HttpContext context)
{
var jsonHelper = new JsonHelper(context);
var url = context.Request["page_url"];
var utf8 = Encoding.UTF8;
url = HttpUtility.UrlDecode(url, utf8);
var config = service.GetShareConfig(url);
jsonHelper.Success("查詢成功", config);
}
/// <summary>
/// 微信認證
/// </summary>
/// <param name="context"></param>
private void Auth(HttpContext context)
{
var token = "alsgame";
var echoStr = context.Request["echoStr"];
var signature = context.Request["signature"];
var timestamp = context.Request["timestamp"];
var nonce = context.Request["nonce"];
string[] ArrTmp = {token, timestamp, nonce};
Array.Sort(ArrTmp); //字典排序
var tmpStr = string.Join("", ArrTmp);
tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
tmpStr = tmpStr.ToLower();
if (tmpStr == signature)
{
if (!string.IsNullOrEmpty(echoStr))
{
context.Response.Write(echoStr);
context.Response.End();
}
}
}
/// <summary>
/// 獲取OpenId
/// </summary>
public void OpenId(HttpContext context)
{
var jsonHelper = new JsonHelper(context);
var code = context.Request["code"];
var obj = service.GetOpenId(code);
jsonHelper.Success("查詢成功", obj);
}
}
}
WxService.cs
using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Security;
using Newtonsoft.Json;
namespace Service
{
/// <summary>
/// 微信業務處理
/// </summary>
public class WxService
{
/// <summary>
/// 微信公眾號
/// </summary>
private static readonly string appId = ConfigurationManager.AppSettings["APPID"];
private static readonly string secret = ConfigurationManager.AppSettings["SECRET"];
/// <summary>
/// 全域性快取
/// </summary>
private static string AccessToken = "";
private static string JsApiTicket = "";
/// <summary>
/// 上次更新時間
/// </summary>
private static long LastAccessToken;
private static long LastJsApiTicket;
/// <summary>
/// 獲取OPENID
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public string GetOpenId(string code)
{
var url =
"https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";
url = string.Format(url, appId, secret, code);
return HttpGet(url);
}
/// <summary>
/// 獲取微信配置資訊
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public WxConfig GetShareConfig(string url)
{
var ticket = GetJsApiTicket();
var noncestr = GetNonceStr();
var timestamp = GetTimeStamp();
var signature = CreateSignature(ticket, noncestr, timestamp, url);
var config = new WxConfig();
config.appId = appId;
config.ticket = ticket;
config.nonceStr = noncestr;
config.timestamp = timestamp;
config.signature = signature;
return config;
}
/// <summary>
/// 生成簽名演算法
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private string CreateSignature(string ticket, string nocestr, long timestamp, string url)
{
var text = "jsapi_ticket=" + ticket;
text += "&noncestr=" + nocestr;
text += "×tamp=" + timestamp;
text += "&url=" + url;
return SHA1(text);
}
/// <summary>
/// 獲取Ticket
/// </summary>
/// <returns></returns>
public string GetJsApiTicket()
{
if (GetTimeStamp() - LastJsApiTicket > 7000)
{
var accessToken = GetAccessToken();
var url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";
url = string.Format(url, accessToken);
var result = HttpGet(url);
var config = JsonConvert.DeserializeObject<WxConfig>(result);
JsApiTicket = config.ticket;
LastJsApiTicket = GetTimeStamp();
}
return JsApiTicket;
}
/// <summary>
/// 獲取Access_Token
/// </summary>
/// <param name="appId"></param>
/// <param name="secret"></param>
/// <returns></returns>
public string GetAccessToken()
{
if (GetTimeStamp() - LastAccessToken > 7000)
{
var url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
url = string.Format(url, appId, secret);
var result = HttpGet(url);
var config = JsonConvert.DeserializeObject<WxConfig>(result);
AccessToken = config.access_token;
LastAccessToken = GetTimeStamp();
}
return AccessToken;
}
/// <summary>
/// 獲取TimeStamp
/// </summary>
/// <returns></returns>
private long GetTimeStamp()
{
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds);
}
/// <summary>
/// 獲取NoceStr
/// </summary>
/// <returns></returns>
private string GetNonceStr()
{
return Guid.NewGuid().ToString();
}
/// <summary>
/// Sha1加密
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private string SHA1(string text)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(text, "SHA1");
}
/// <summary>
/// http請求
/// </summary>
/// <param name="url"></param>
/// <param name="postDataStr"></param>
/// <returns></returns>
public string HttpGet(string url)
{
var request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "text/json;charset=UTF-8";
var response = (HttpWebResponse) request.GetResponse();
var myResponseStream = response.GetResponseStream();
var streamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
var result = streamReader.ReadToEnd();
streamReader.Close();
myResponseStream.Close();
return result;
}
}
}
JsonHelper.cs
using System;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Service
{
/// <summary>
/// JSON輔助類
/// </summary>
public class JsonHelper
{
private readonly HttpContext context;
public JsonHelper(HttpContext context)
{
this.context = context;
}
/// <summary>
/// 處理成功
/// </summary>
public void Success(string msg, object data = null)
{
var message = new Message();
message.status = 0;
message.msg = msg;
message.data = data == null ? new Array[0] : data;
message.updateTime = DateTime.Now;
context.Response.Write(SerializeObject(message));
}
/// <summary>
/// 處理失敗
/// </summary>
public void Failure(string msg, object data = null)
{
var message = new Message();
message.status = -1;
message.msg = msg;
message.data = data == null ? new Array[0] : data;
message.updateTime = DateTime.Now;
context.Response.Write(SerializeObject(message));
}
/// <summary>
/// 序列化
/// </summary>
public string SerializeObject(object obj)
{
var timeFormat = new IsoDateTimeConverter();
timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
return JsonConvert.SerializeObject(obj, Formatting.Indented, timeFormat);
}
}
}
實體類
WxConfig.cs
namespace Service
{
public class WxConfig
{
public string appId { get; set; }
public string signature { get; set; }
public string nonceStr { get; set; }
public long timestamp { get; set; }
public string ticket { get; set; }
public string access_token { get; set; }
}
}
Message.cs
using System;
namespace Service
{
public class Message
{
/// <summary>
/// 響應狀態碼
/// </summary>
public int status { get; set; }
/// <summary>
/// 響應訊息
/// </summary>
public string msg { get; set; }
/// <summary>
/// 響應資料集
/// </summary>
public object data { get; set; }
/// <summary>
/// 伺服器時間
/// </summary>
public DateTime updateTime { get; set; }
}
}