微信公众号开发 (微信网页开发)

  微信支付搞完之后,也开始了微信其他功能,不得不说,微信写得接口都比较齐全和标准,附上微信公众号开发文档链接,仔细阅读,必须严格按照其规则,才能调用微信的接口。

  最近做了一个手机端调用微信接口打开摄像头进行扫描二维码功能和调用上传下载图片的接口,注意,在微信公众号配置要注意,【开发】-【接口权限】 查看对应的接口权限是开通了没有?最主要的是,还要在【公众号设置】-【功能设置】-【JS接口安全域名】配置,切记,一定是备案过的,一级二级都可以

附上图片:

配置完此项之后,还有个地方需要配置的,需要特别注意的是这边的配置,【开发】-【基本配置】

  需要注意的是,该配置是微信验证该域名是否是用于请求的正确性,说白了,就是微信要确认这个是可以通信的域名服务器,那么规则是写一个验证(当然,验证这步可以跳过),微信会请求该Url,传参数echoStr,我们只要原样返回该参数即可

附上源码:

 public class GetEchoStrController : Controller
    {
        [AllowAnonymous]
        [HttpGet]
        public string GetEchoStr(string echostr)
        {
            return echostr;
        }
    }

这样,微信就通过了,然后就可以配置Token(自定义),EncodingAESKey(自定义),消息加密方式,暂时选择【明文模式】。

  完成以上的配置之后,便可以进行微信接口的调用了。

  调用接口前,要先获取下相关的配置,仔细详读微信开发文档

  获取必要的参数:GetConfig() ,要获取Token之后获取Tiket,通过签名,将参数传到前端,调用微信接口。

    public class WechatController : BaseAPIController
    {
        #region 微信端图片上传配置
      /// <summary> /// 获取Token /// </summary> /// <returns></returns> public static string GetToken(WechatConfig entity,ref long tokenOverTime,ref long tokenCreatTime) { //过期 if (IsOverdue(entity.TokenOverTime, entity.TokenCreateTime)) { string getUrl = @"https://api.weixin.qq.com/cgi-bin/token?"; WebUtils webser = new WebUtils(); IDictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("grant_type", "client_credential"); dic.Add("appid", entity.Appkey); dic.Add("secret", entity.AppSecret); var token = webser.DoGet(getUrl, dic); JavaScriptSerializer json = new JavaScriptSerializer(); Token tok = json.Deserialize<Token>(token); tokenOverTime =tok.expires_in; tokenCreatTime = (long)DateTime.UtcNow.Subtract(DateTime.Parse("1970-01-01 00:00:00")).TotalMilliseconds; return tok.access_token; } else { tokenOverTime = entity.TokenOverTime; return entity.Token; } } /// <summary> /// 更新参数 /// </summary> /// <param name="entity"></param> private static void UpdateWechatConfig(WechatConfig entity) { } /// <summary> /// 实体转Json /// </summary> /// <typeparam name="T"></typeparam> /// <param name="jsonObject"></param> /// <returns></returns> private static string Model2Json<T>(T jsonObject) { using (var ms = new MemoryStream()) { new DataContractJsonSerializer(typeof(T)).WriteObject(ms, jsonObject); return Encoding.UTF8.GetString(ms.ToArray()); } } /// <summary> /// 获取Tiket /// </summary> /// <param name="token"></param> /// <returns></returns> private string GetTiket(WechatConfig entity) { if (IsOverdue(entity.TiketOverTime, entity.TiketCreateTime)) { string getUrl = @"https://api.weixin.qq.com/cgi-bin/ticket/getticket?"; WebUtils webser = new WebUtils(); IDictionary<string, string> dic = new Dictionary<string, string>(); long tokenOverTime = entity.TokenOverTime; long tokenCreateTime = entity.TokenCreateTime; var token = GetToken(entity,ref tokenOverTime,ref tokenCreateTime); dic.Add("access_token", token); dic.Add("type", "jsapi"); var tiket = webser.DoGet(getUrl, dic); JavaScriptSerializer json = new JavaScriptSerializer(); Ticket tic = json.Deserialize<Ticket>(tiket); entity.Tiket = tic.ticket; entity.TiketCreateTime = (long)DateTime.UtcNow.Subtract(DateTime.Parse("1970-01-01 00:00:00")).TotalMilliseconds; entity.TiketOverTime = tic.expires_in; entity.Token = token; entity.TokenOverTime = tokenOverTime; entity.TokenCreateTime = tokenCreateTime; UpdateWechatConfig(entity); return tic.ticket; } else { return entity.Tiket; } } /// <summary> /// 获取配置 /// </summary> /// <returns></returns> public static WechatConfig GetConfigParams() {
       var entity=GetParams();
var param = entity.Params; JavaScriptSerializer json = new JavaScriptSerializer(); var config = json.Deserialize<WechatConfig>(param); return config; } /// <summary> /// Token参数 /// </summary> public class Token { public string access_token { get; set; } public long expires_in { get; set; } } /// <summary> /// Ticket参数 /// </summary> public class Ticket { public int errcode { get; set; } public string errmsg { get; set; } public long expires_in { get; set; } public string ticket { get; set; } } /// <summary> /// 配置 /// </summary> public class Config { public string appId { get; set; } public string timestamp { get; set; } public string nonceStr { get; set; } public string signature { get; set; } } /// <summary> /// 获取十位的时间戳 /// </summary> /// <param name="dt"></param> /// <returns></returns> private static string GenerateTimeStamp(DateTime dt) { // Default implementation of UNIX time of the current UTC time TimeSpan ts = dt.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /// <summary> /// 给请求签名 /// </summary> /// <param name="parameters">所有字符型的请求参数</param> /// <param name="secret">签名密钥</param> /// <param name="qhs">是否前后都加密进行签名</param> /// <returns></returns> private static string SignRequest(IDictionary<string, string> parameters) { // 第一步:把字典按Key的字母顺序排序 IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters); IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator(); // 第二步:把所有参数名和参数值串在一起 StringBuilder query = new StringBuilder(); while (dem.MoveNext()) { string key = dem.Current.Key; string value = dem.Current.Value; if (!string.IsNullOrWhiteSpace(key))//!string.IsNullOrWhiteSpace(value) 空值也加入计算?? { query.Append(key + "=").Append(value + "&"); } } var str = query.ToString(); if (str.Length > 0) { str = str.Substring(0, str.Length - 1); } // 第三部:使用sha1 var result = Utils.EncryptToSHA1(str); return result; } /// <summary> /// 随机数 /// </summary> /// <returns></returns> private string Random() { return Guid.NewGuid().ToString().Replace("-", ""); } public class HttpParams { public string url { get; set; } public TimeSpan timestamp { get; set; } public string signature { get; set; } public string nonce { get; set; } public string echostr { get; set; } } /// <summary> /// 获取配置 /// </summary> /// <returns></returns> [HttpPost] public Result<Config> ErpGetConfig(HttpParams httpParams) { WechatConfig wechatconfig = GetConfigParams(); if (wechatconfig == null) { return new Result<Config>(); } var nonceStr = Random(); var timestamp = GenerateTimeStamp(DateTime.Now); IDictionary<string, string> parameters = new Dictionary<string, string>(); parameters.Add("jsapi_ticket", GetTiket(wechatconfig)); parameters.Add("noncestr", nonceStr.ToLower()); parameters.Add("timestamp", timestamp); parameters.Add("url", HttpUtility.UrlDecode(httpParams.url)); var signature = SignRequest(parameters); Config config = new Config(); config.appId = wechatconfig.Appkey; config.timestamp = timestamp; config.nonceStr = nonceStr; config.signature = signature; return new Result<Config>(config); } /// <summary> /// 检查Tiket是否过期 /// </summary> /// <returns></returns> private static bool IsOverdue(long overTime, long createTime) { long spanNow = (long)DateTime.UtcNow.Subtract(DateTime.Parse("1970-01-01 00:00:00")).TotalMilliseconds; long spanCreate = createTime; return (spanNow - spanCreate > overTime * 1000); } /// <summary> /// 下载保存多媒体文件,返回多媒体保存路径 /// </summary> /// <param name="ACCESS_TOKEN"></param> /// <param name="MEDIA_ID"></param> /// <returns></returns> public static string GetMultimedia(string serverId,Guid id) { Utils.WriteLog(DateTime.Now+":The Pic's Serverid:"+serverId); WechatConfig wechatConfig = GetConfigParams(); if (wechatConfig == null) { return string.Empty; } if (string.IsNullOrEmpty(serverId)) { return null; } Result r = new Result(); string strpath = string.Empty; string savepath = string.Empty; string file = string.Empty; long overtime = 0; long date = 0; string stUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + GetToken(wechatConfig, ref overtime, ref date) + "&media_id=" + serverId; HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(stUrl); req.Method = "GET"; using (WebResponse wr = req.GetResponse()) { HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse(); strpath = myResponse.ResponseUri.ToString(); WebClient mywebclient = new WebClient(); savepath = System.Web.Hosting.HostingEnvironment.MapPath(WebConfigUtils.GetAppSettingsInfo("ImagePath")) + "UploadImages\" + id; if (!Directory.Exists(savepath)) { Directory.CreateDirectory(savepath); } savepath = Path.Combine(savepath, id + ".jpg"); try { mywebclient.DownloadFile(strpath, savepath); file = Path.Combine(WebConfigUtils.GetAppSettingsInfo("ImagePath") + "UploadImages\" + id, id + ".jpg"); } catch (Exception ex) { r.ErrorMessage = ex.Message; r.OperationTime = DateTime.Now; r.ResultCode = ResultCode.Error; Utils.WriteLog(ex); } } return file; }
#endregion

    }
public class WechatConfig
    {
        public long TokenOverTime { get; set; }
        public long TiketOverTime { get; set; }
        public string Token { get; set; }
        public string Tiket { get; set; }
        public long TokenCreateTime { get; set; }
        public long TiketCreateTime { get; set; }
        public string Appkey { get; set; }
        public string AppSecret { get; set; }
        public Guid InfOauthDetailID { get; set; }
    }

主要是获取需要的参数,然后去获取需要的Token和Tiket(微信调接口所需要),之后,组织成需要的,抛给前端处理调用微信接口,对了,这里还忘了,token跟tiket不仅要检查是不是过期了,还要检查是否失效了,233333,这里少了个检查是否失效,后面补上。前端的东西,就看微信开发文档,很仔细。

  觉得写得可以,帮忙顶一下。

        

   QQ交流群:523490820

  

明明可以靠才华吃饭,非要靠脸~
原文地址:https://www.cnblogs.com/lycsmzl/p/6054525.html