asp.net 통합 위챗, 스파이크

모바일 애플리케이션은 보통 두 가지인데 하나는 네이티브 앱이고 하나는 H5다.H5는 브라우저에서 실행되지만 사용자가 휴대전화에 인터넷 주소를 입력하도록 하는 것은 정말 좋은 생각이 아니다.그래서 H5를 유행하고 개방된 앱에 기생시키는 것이 우선이다.현재는 주로 위챗으로 이 두 가지 응용 프로그램이 유행하고 개방적인 요구를 충족시킬 수 있다.다음은 asp. 기반입니다.net에서 개발한 H5 응용 프로그램은 어떻게 위챗 기업 번호, 못과 통합할 수 있습니까?먼저 이 두 앱의 개발 문서를 보면 두 가지가 놀랍게도 비슷하다는 것을 알 수 있다. 이로써 우리는 통합을 더욱 절약할 수 있고 자연스럽게 하나의 인터페이스를 정의한 다음에 위챗과 스파이크를 각각 실현할 수 있다.1 커넥터는 다음과 같습니다.
/// 
    ///     app(   ,  )     
    /// 
    public interface IApp
    {
        int PID4CropID { get; }
        int PID4AppSecret { get; }
        int PID4AgentID { get; }
        string URL4AccessToken { get; }
        string URL4Ticket { get; }
        string URL4GetUser { get; }
        string URL4SendMsg { get; }
        string UserIDKey { get; }
        string UserIDFieldName { get; }
        string GetMediaDownloadUrl(string mediaId);
    }

2 微信实现类

/// 
    ///   
    /// 
    public class WxApp : IApp
    {
        public int PID4AgentID
        {
            get
            {
                return 202;
            }
        }

        public int PID4AppSecret
        {
            get
            {
                return 201;
            }
        }

        public int PID4CropID
        {
            get
            {
                return 200;
            }
        }

        public string URL4AccessToken
        {
            get
            {
                return "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}";
            }
        }
        public string URL4GetUser
        {
            get
            {
                return "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={0}&code={1}&agentid={2}";
            }
        }

        public string URL4SendMsg
        {
            get
            {
                return "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}";
            }
        }

        public string URL4Ticket
        {
            get
            {
                return "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token={0}";
            }
        }

        public string UserIDFieldName
        {
            get
            {
                return "OpenID";
            }
        }

        public string UserIDKey
        {
            get
            {
                return "UserId";
            }
        }

        public string GetMediaDownloadUrl(string mediaId)
        {
            return string.Format("https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}", AppServer.GetAccessToken(this), mediaId);
        }
    }

3 钉钉实现类

/// 
    ///   
    /// 
    public class DDApp : IApp
    {
        public int PID4AgentID
        {
            get
            {
                return 302;
            }
        }
        public int PID4AppSecret
        {
            get
            {
                return 301;
            }
        }

        public int PID4CropID
        {
            get
            {
                return 300;
            }
        }

        public string URL4AccessToken
        {
            get
            {
                return "https://oapi.dingtalk.com/gettoken?corpid={0}&corpsecret={1}";
            }
        }

        public string URL4GetUser
        {
            get
            {
                return "https://oapi.dingtalk.com/user/getuserinfo?access_token={0}&code={1}";
            }
        }
        public string URL4SendMsg
        {
            get
            {
                return "https://oapi.dingtalk.com/message/send?access_token={0}";
            }
        }
        public string URL4Ticket
        {
            get
            {
                return "https://oapi.dingtalk.com/get_jsapi_ticket?access_token={0}";
            }
        }
        public string UserIDFieldName
        {
            get
            {
                return "DDID";
            }
        }
        public string UserIDKey
        {
            get
            {
                return "userid";
            }
        }
        public string GetMediaDownloadUrl(string mediaId)
        {
            return mediaId;
        }
    }

4 获取tickit,token,Signature,实现自动登陆,从微信或钉钉服务器上下载手机上传的图片等

public class AppServer
    {
        internal static string GetSignature(long timeStamp, string url, string cropId, string appSecret, IApp app)
        {
            var token = GetTicket(cropId, appSecret,app);
            var str = string.Format("jsapi_ticket={0}&noncestr=CwgHd0EAGathMlxt&timestamp={1}&url={2}", token, timeStamp, url.Replace(":80/", "/"));
            return SHA1Encrypt(str).ToLower();
        }
        internal static string SHA1Encrypt(string str)
        {
            byte[] StrRes = Encoding.Default.GetBytes(str);
            HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
            StrRes = iSHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte iByte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", iByte);
            }
            return EnText.ToString();
        }
        internal static string GetAccessToken(IApp app,string cropId = null, string appSecret = null)
        {
            if (cropId == null) cropId = ProfileMan.GetProfileValue(app.PID4CropID);
            if (appSecret == null) appSecret = ProfileMan.GetProfileValue(app.PID4AppSecret);
            return GetToken(false, cropId, appSecret,app);
        }

        internal static string GetTicket(string cropId, string appSecret, IApp app)
        {
            return GetToken(true, cropId, appSecret,app);
        }

        private static string GetToken(bool isGetTicket, string cropId, string appSecret, IApp app)
        {
            var prefix = SessionHelper.CloudMode ? SessionHelper.CurrentDBName : string.Empty;
            var appType = app is DDApp ? 2 : 1;
            var key = string.Format("{0}_{1}_{2}_{3}_{4}", prefix, cropId, appSecret, isGetTicket ? 1 : 0, appType);
            if (HttpRuntime.Cache.Get(key) == null)
            {
                CacheAccessToken(appType, isGetTicket, prefix, cropId, appSecret);
            }

            return (string)HttpRuntime.Cache.Get(key);
        }

        private static void CacheAccessToken(int appType, bool isGetTicket, string prefix, string cropId, string appSecret)
        {
            var key = string.Format("{0}_{1}_{2}_{3}_{4}", prefix, cropId, appSecret, isGetTicket ? 1 : 0, appType);
            IApp app = AppIntegerUtil.CreateApp(appType);
            int expiresMin;
            var url = !isGetTicket ? string.Format(app.URL4AccessToken, cropId, appSecret) : string.Format(app.URL4Ticket, GetAccessToken(app, cropId, appSecret));
            var jsonKey = !isGetTicket ? "access_token" : "ticket";
            HttpRuntime.Cache.Add(key, GetDataFromServer(url, jsonKey, out expiresMin), null, DateTime.Now.AddSeconds(expiresMin), Cache.NoSlidingExpiration, CacheItemPriority.Normal, CacheItemRemovedCallback);
        }

        internal static string GetUserID(Entities objContext, string code, IApp app)
        {
            int expiresMin;
            return GetDataFromServer(string.Format(app.URL4GetUser, GetAccessToken(app, ProfileMan.GetProfileValue(app.PID4CropID, objContext), ProfileMan.GetProfileValue(app.PID4AppSecret, objContext)), code, ProfileMan.GetProfileValue(app.PID4AgentID, objContext)), app.UserIDKey, out expiresMin, false);
        }
        private static void CacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason)
        {
            var keys = key.Split('_');
            if (keys.Length == 5) CacheAccessToken(Convert.ToInt32(keys[4]), keys[3] == "1", keys[0], keys[1], keys[2]);
        }

        private static string GetDataFromServer(string url, string jsonKey, out int expiresMin, bool hasExpiresMin=true)
        {
            expiresMin = 7200;
            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Method = "GET";

            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
            string responseContent = streamReader.ReadToEnd();

            httpWebResponse.Close();
            streamReader.Close();
            var jo = JObject.Parse(responseContent);
            JToken v;
            if (jo.TryGetValue(jsonKey, out v))
            {
                expiresMin = hasExpiresMin ? Convert.ToInt32(jo["expires_in"]) : 0;
                return v.ToString();
            }

            return null;
        }

        internal static bool DownloadMediaFromAppServer(IApp app, string mediaId, string fileName)
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(app.GetMediaDownloadUrl(mediaId));
            req.Method = "GET";
            HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();
            WebClient webClient = new WebClient();
            var success = true;
            try
            {
                webClient.DownloadFile(myResponse.ResponseUri.ToString(), fileName);
            }
            catch(Exception err)
            {
                LogManager.GetLogger(typeof(AppServer)).Error(err);
                success = false;
            }

            return success;
        }
    }

5js 핸드폰 단말기 호출 카메라나 갤러리 이미지 업로드 실현
if (appType == 'wx') {
                    wx.chooseImage({
                        count: 1, //   9
                        sizeType: ['original', 'compressed'], //             ,      
                        sourceType: ['album', 'camera'], //              ,      
                        success: function (res) {
                            img[0].src = res.localIds; //          ID  ,localId    img   src      
                            wx.uploadImage({
                                localId: res.localIds.toString(), //           ID, chooseImage    
                                isShowProgressTips: 1, //    1,      
                                success: function (res) {
                                    img.attr('serverid', res.serverId); //          ID
                                }
                            });
                        }
                    });
                }
                else if (appType == 'dd') {
                    dd.biz.util.uploadImage({
                        onSuccess: function (result) {
                            if (result.length > 0) {
                                img[0].src = result[0];
                                img.attr('serverid', result[0]);
                            }
                        },
                        onFail: function (result) {
                            alert(JSON.stringify(result));
                        }
                    });
                }

이로써 위챗 기업 번호, 스파이크의 통합, 주요 기능: 자동 로그인, 휴대전화 사진 업로드, 사용자에게 메시지 발송을 실현했다.기타 액세스 사용자 목록, 부서 정보 등은 봉인할 수 있다.

좋은 웹페이지 즐겨찾기