【说明】:访客用户和外来施工人员用微信服务号;职工人员(内部人员)用企业微信号(企业号)
1、微信公众平台——服务号:
(1)、从服务号授权获取信息登录的入口有:访客入口端和外来施工人员入口端两个。下面代码是用访客的为例。
#region 微信工作平台——服务号之访客授权入口逻辑代码
public ActionResult VisitorEntrance()
{
#region 变量
string URL = "";//跳转链接
string AvatarPath = "";//微信头像路径
string openid = "";//微信唯一标识
string access_token = "";//凭证
#endregion
#region 处理
try
{
//查询访客入口状态
DataTable dt = myWorkersLoginModels.SelectSystemModuleFunctionByCodeName("VE");
if (dt.Rows.Count > 0 && dt != null)
{
//获取用户禁用否状态
bool WhetherToEnable = dt.Rows[0].IsNull("WhetherToEnable") !=
true ? Convert.ToBoolean(dt.Rows[0]["WhetherToEnable"]) : false;
if (!WhetherToEnable)//访客端入口被禁用了
{
//访客入口已经禁用无法登录!
URL = "/Erro/VPermissionsErro?type=1";//跳到错误提示页面
}
else//访客端入口正常的
{
#region 第一步:用户同意授权,获取code
//授权登录获取code值
string code = Request.QueryString["code"];
if (code == null || code == "")//如果获取的code值为空
{
//中断不往下执行
return Redirect("/Erro/VPermissionsErro?type=4");//微信拉取信息失败,跳到错误提示页面
}
#endregion
#region 第二步:通过code换取网页授权access_token和openid
string Get_Access_Token_Url = string.Format(
AccessTokenHelp.Get_Access_Token_Url,//获取access_token的链接
//公众号的唯一标识(我们此参数保存在数据库的,读者可以直接写你们公众号对应的参数)
Utils.getWeChatParameter(8, myCcflow2),
//公众号的appsecret(我们此参数保存在数据库的,读者可以直接写你们公众号对应的参数)
Utils.getWeChatParameter(9, myCcflow2),
code);//填写第一步获取的code参数
//调用方法发送请求给微信服务器
string result = HttpUtility.RequestToWeChat(Get_Access_Token_Url);
AccessToken at = new AccessToken();//实例化实体类
JavaScriptSerializer j = new JavaScriptSerializer();//实例化封装类
at = j.Deserialize<AccessToken>(result);//封装到实体类
access_token = at.access_token;//获取用户的access_token
openid = at.openid;//获取用户的openid,相对于公众号是唯一的
#endregion
// 3 第三步:刷新access_token(如果需要)
DataTable dtVisitor = null; //声明访客信息DataTable
if ((openid != "" && openid != null && openid.Length > 0) &&
(access_token != "" && access_token != null && access_token.Length > 0))
{//access_token值 和 openid值 获取成功
//通过openid查询数据库此用户是否存在
dtVisitor = myWeChatModels.selectVisitorWhetherPresence(openid);
}
else//access_token值 和 openid值获取失败
{
//中断不往下执行
return Redirect("/Erro/VPermissionsErro?type=4");//微信拉取信息失败,跳到错误提示页面
}
#region 如果查到有用户数据,说明用户从微信登录过,就直接重定向跳转到主页面
if (dtVisitor != null && dtVisitor.Rows.Count == 1)//直接跳到主界面
{
int StateID = Convert.ToInt32(dtVisitor.Rows[0]["StateID"]);//获取用户状态ID
#region 判断该访客是否是 从访客转为施工人员禁用,如果是,再判断是否可以修改回来正常状态
if (StateID != (int)enumStateID.StateID_1)
{
string IDCard = dtVisitor.Rows[0].IsNull("IDCard") !=
true ? dtVisitor.Rows[0]["IDCard"].ToString() : "";
Utils.AtuoUpdateVisitorStateIDToType2(
ref StateID, IDCard, Convert.ToInt32(dtVisitor.Rows[0]["VisitorUserID"]));
}
#endregion
if (StateID != 1)//该状态用户被禁用了
{
URL = "/Erro/VPermissionsErro?type=3";//重定向跳到错误提示页面
}
else//用户正常
{
myWeChatModels.updateVisitorUserLoginCount(openid);//登录次数+1
//将用户信息存到Cookie值,1:代表微信入口登录的;2:代表手机号加手机验证码登录的
myCookie.setVisitorLogin(Convert.ToInt32(dtVisitor.Rows[0]["VisitorUserID"]), 1);
//重定向到主页面
URL = "/Main/VisitorMain";
}
}
#endregion
#region 没登录过,需要注册
else
{
#region 4 第四步:拉取用户微信信息(需链接的scope参数为 snsapi_userinfo)
string Get_Details_Url = string.Format(
AccessTokenHelp.Get_Details_Url,//拉取用户信息链接
access_token,//网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
openid);//用户的唯一标识
//调用方法发送请求给微信服务器
string jsonstrContent = HttpUtility.RequestToWeChat(Get_Details_Url);
AuthorizedUser au = new AuthorizedUser();//用户信息字段类实例化
au = j.Deserialize<AuthorizedUser>(jsonstrContent);//封装到实体类
AvatarPath = au.headimgurl;//获取微信头像路径
#endregion
//重定向到注册页面
URL = "/VisitorLogin/Enroll?openid=" + openid + "&AvatarPath=" + AvatarPath;
}
#endregion
}
}
else//没有获取到功能模块代码
{
URL = "/Erro/VPermissionsErro?type=2";//重定向跳到错误提示页面
}
}
catch (Exception ex)
{
//微信授权登录异常
URL = "/Erro/VPermissionsErro?type=5";
//输出异常信息到指定文件夹文本
Utils.WriteTxt("访客端微信授权登录异常,ex:" + ex.Message + ",StackTrace:" + ex.StackTrace);
}
#endregion
return Redirect(URL);//页面重定向跳转
}
#endregion
2、
微信公众平台——
企业微信号:
#region 微信“企业微信号”--职工人员授权入口
public ActionResult WorkersEntranceByEnterprise()
{
#region 变量
string openid = "";//微信唯一标识
string URL = "";//跳转链接
string access_token = string.Empty;//access_token凭证值,Empty:只读
JavaScriptSerializer j = new JavaScriptSerializer(); //实例化对象封装类
#endregion
#region 逻辑处理
try
{
//查询职工入口状态
DataTable dt = myWorkersLoginModels.SelectSystemModuleFunctionByCodeName("SE");
if (dt != null && dt.Rows.Count > 0)
{
//入口状态
bool WhetherToEnable = dt.Rows[0].IsNull("WhetherToEnable") !=
true ? Convert.ToBoolean(dt.Rows[0]["WhetherToEnable"]) : false;
if (!WhetherToEnable)//职工入口被禁用了
{
URL = "/Erro/WPermissionsErro?type=1";//重定向跳到错误提示页面
}
else//职工入口正常的
{
#region 1 第一步:用户同意授权后跳转到此,获取code
string code = Request.QueryString["code"]; //授权登录获取code值
if (code == null || code == "")
{
//中断不往下执行
return Redirect("/Erro/WPermissionsErro?type=4");//微信拉取信息失败,重定向跳到错误提示页面
}
#endregion
#region 第二步:获取access_token值
//获取应用access_token的连接
string get_access_token_url = string.Format(AccessTokenHelp.get_access_token_url,
//企业CorpID(我们此参数保存在数据库的,读者可以直接写你们公众号对应的参数)
Utils.getWeChatParameter(10, myCcflow2),
//应用密钥(我们此参数保存在数据库的,读者可以直接写你们公众号对应的参数)
Utils.getWeChatParameter(11, myCcflow2));
string result = HttpUtility.RequestToWeChat(get_access_token_url);//调用发送请求方法
EnterpriseAccessToken eat = new EnterpriseAccessToken();//实例化实体类
eat = j.Deserialize<EnterpriseAccessToken>(result);//封装到实体类
if (eat.errcode == "0")//成功返回
{
access_token = eat.access_token;//得到access_token值
}
if (access_token == "")
{
//中断不往下执行
return Redirect("/Erro/WPermissionsErro?type=4");//微信拉取信息失败,重定向跳到错误提示页面
}
#endregion
#region 第三步:获取成员信息(UserID)
//获取成员信息的连接
string get_member_information_url = string.Format(
AccessTokenHelp.get_member_information_url,//链接
access_token,//access_token值
code);//code值
//调用发送请求方法
string MemberInformation = HttpUtility.RequestToWeChat(get_member_information_url);
EnterpriseMemberInformation emi = new EnterpriseMemberInformation();//实例化实体类
emi = j.Deserialize<EnterpriseMemberInformation>(MemberInformation);//封装到实体类
string UserID = string.Empty;
if (emi.errcode == "0")//成功返回
{
UserID = emi.UserId;//成员id,企业号的唯一标识
openid = UserID;
}
if (openid == "")
{
//中断不往下执行
return Redirect("/Erro/WPermissionsErro?type=4");//微信拉取信息失败,重定向跳到错误提示页面
}
else
{
//通过得到的openid值查询数据库
DataTable dtWorker = myWeChatModels.SelectWorkerByOpenid(openid);
if (dtWorker !=null&& dtWorker.Rows.Count > 0)//数据库有UserID了
{
//获取职工用户的一些基本信息用于存Cookie值
string strUserName = dtWorker.Rows[0].IsNull("sAMAccountName") !=
true ? dtWorker.Rows[0]["sAMAccountName"].ToString() : "";//职工工号
int StateID = dtWorker.Rows[0].IsNull("StateID") !=
true ? Convert.ToInt32(dtWorker.Rows[0]["StateID"]) : 0;//状态
long LoginCount = dtWorker.Rows[0].IsNull("LoginCount") !=
true ? Convert.ToInt64(dtWorker.Rows[0]["LoginCount"]) : 0;//登录次数
string AvatarPath = dtWorker.Rows[0].IsNull("AvatarPath") !=
true ? dtWorker.Rows[0]["AvatarPath"].ToString() : "";//头像路径
string cn = dtWorker.Rows[0].IsNull("cn") !=
true ? dtWorker.Rows[0]["cn"].ToString() : "";//名称
string description = dtWorker.Rows[0].IsNull("description") !=
true ? dtWorker.Rows[0]["description"].ToString() : "";//性别
string department = dtWorker.Rows[0].IsNull("department") !=
true ? dtWorker.Rows[0]["department"].ToString() : "";//部门
string oneOU = dtWorker.Rows[0].IsNull("oneOU") !=
true ? dtWorker.Rows[0]["oneOU"].ToString() : "";//一级OU
string towOU = dtWorker.Rows[0].IsNull("towOU") !=
true ? dtWorker.Rows[0]["towOU"].ToString() : "";//二级OU
string threeOU = dtWorker.Rows[0].IsNull("threeOU") !=
true ? dtWorker.Rows[0]["threeOU"].ToString() : "";//三级OU
string title = dtWorker.Rows[0].IsNull("title") !=
true ? dtWorker.Rows[0]["title"].ToString() : "";//岗位
string businessRoles = dtWorker.Rows[0].IsNull("businessRoles") !=
true ? dtWorker.Rows[0]["businessRoles"].ToString() : "";//职务
string businessCategory = dtWorker.Rows[0].IsNull("businessCategory") !=
true ? dtWorker.Rows[0]["businessCategory"].ToString() : "";//行政职级
string mobile = dtWorker.Rows[0].IsNull("mobile") !=
true ? dtWorker.Rows[0]["mobile"].ToString() : "";//手机号码
if (StateID != (int)enumStateID.StateID_1)
{
//中断不往下执行
return Redirect("/Erro/WPermissionsErro?type=3");//用户被禁用了
}
else
{
#region cookie 存值
myCookie.setStaffEntrance(strUserName, StateID, LoginCount,
cn, description, department, oneOU, towOU, threeOU,
title, businessRoles, businessCategory, mobile, AvatarPath,
myWorkersLoginModels);
#endregion
myWorkersLoginModels.UpdateLoginCount(LoginCount + 1, strUserName); //修改登录次数
URL = "/Main/WorkersMain";//重定向跳转到主页面
}
}
else
{
//跳到绑定界面
URL = "/WeChat/WorkBindingWeChat?openid=" + openid;
}
}
#endregion
}
}
else//没有获取到功能模块代码
{
URL = "/Erro/WPermissionsErro?type=2";//重定向跳到错误提示页面
}
}
catch (Exception ex)
{
//微信授权登录异常
URL = "/Erro/WPermissionsErro?type=5";//重定向跳到错误提示页面
Utils.WriteTxt("ex:" + ex.Message + ",StackTrace:" + ex.StackTrace);//输出错误信息
}
#endregion
return Redirect(URL);//页面重定向跳转
}
#endregion
3、
用到自定义的一些帮助类
(1)请求链接类
/// <summary>
/// 请求链接类
/// </summary>
public static class AccessTokenHelp
{
#region 服务号
//获取网页授权access_token值的链接
public static string Get_Access_Token_Url =
"https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code= {2}&grant_type=authorization_code";
//拉取用户信息链接
public static string Get_Details_Url =
"https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN ";
#endregion
#region 企业微信号
//获取应用access_token的链接
public static string get_access_token_url =
"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}";
//获取成员信息的链接
public static string get_member_information_url =
"https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={0}&code={1}";
//拉取成员详情信息的链接
public static string get_member_Details_url =
"https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token={0}";
#endregion
}
/// <summary>
/// access_token实体类
/// </summary>
public class AccessToken
{
//网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
public string access_token { get; set; }
//access_token接口调用凭证超时时间,单位(秒)
public string expires_in { get; set; }
//用户刷新access_token
public string refresh_token { get; set; }
//用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
public string openid { get; set; }
//用户授权的作用域,使用逗号(,)分隔
public string scope { get; set; }
}
/// <summary>
/// 用户信息实体类
/// </summary>
public class AuthorizedUser
{
public string openid { get; set; }//用户的唯一标识
public string nickname { get; set; }//用户昵称
public string sex { get; set; }//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
public string province { get; set; }//用户个人资料填写的省份
public string city { get; set; }//普通用户个人资料填写的城市
public string country { get; set; }//国家,如中国为CN
public string headimgurl { get; set; }//用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,
//0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
public string unionid { get; set; }//只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
}
using GraduateSystem;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace VisitorSysMobile
{
/// <summary>
/// Http请求帮助类
/// </summary>
public static class HttpUtility
{
/// <summary>
/// get请求方法
/// </summary>
/// <param name="url">请求链接</param>
/// <returns></returns>
public static string GetRequestToWeChat(string url)
{
string result = string.Empty;//声明只读空字符串
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);//请求url
request.Method = "GET";//get请求方式
HttpWebResponse response = (HttpWebResponse)request.GetResponse();//得到请求响应
StreamReader sr = new StreamReader(response.GetResponseStream());//发送请求
result = sr.ReadToEnd();//获取请求结果
}
catch (Exception ex)
{
Utils.WriteTxt("get请求异常,ex:" + ex.Message + ",StackTrace:" + ex.StackTrace);
}
return result;//返回结果
}
/// <summary>
/// get发送请求(含请求包)
/// </summary>
/// <param name="url">Url地址</param>
/// <param name="method">方法(post或get)</param>
/// <param name="method">数据类型</param>
/// <param name="requestData">数据</param>
public static string SendGetHttpRequest(string url, string contentType)
{
string result = string.Empty;//声明只读空字符串
try
{
WebRequest request = (WebRequest)HttpWebRequest.Create(url);//请求url
request.Method = "get";//get请求方式
request.ContentType = contentType;//请求包(请求体)
using (WebResponse response = request.GetResponse())//得到请求响应
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())//发送请求
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();//获取请求结果
}
}
}
}
}
catch (Exception ex)
{
Utils.WriteTxt("get发送请求体异常,ex:" + ex.Message + ",StackTrace:" + ex.StackTrace);
}
return result;//返回结果
}
/// <summary>
/// post请求方法
/// </summary>
/// <param name="url">请求链接</param>
/// <returns></returns>
public static string PostRequestToWeChat(string url)
{
string result = string.Empty;//声明只读空字符串
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);//请求url
request.Method = "POST";//post请求方式
HttpWebResponse response = (HttpWebResponse)request.GetResponse();//得到请求响应
StreamReader sr = new StreamReader(response.GetResponseStream());//发送请求
result = sr.ReadToEnd();//获取请求结果
}
catch (Exception ex)
{
Utils.WriteTxt("post请求异常,ex:" + ex.Message + ",StackTrace:" + ex.StackTrace);
}
return result;//返回结果
}
/// <summary>
/// post发送请求(含请求包)
/// </summary>
/// <param name="url">Url地址</param>
/// <param name="method">方法(post或get)</param>
/// <param name="method">数据类型</param>
/// <param name="requestData">数据</param>
public static string SendPostHttpRequest(string url, string requestData)
{
string result = string.Empty;//声明只读空字符串
try
{
WebRequest request = (WebRequest)HttpWebRequest.Create(url);//请求url
request.Method = "POST";//post请求方式
request.ContentType = "application/json;charset=UTF-8";//请求体编码类型
byte[] postBytes = null;//定义字节
postBytes = Encoding.UTF8.GetBytes(requestData);//将请求体编码
request.ContentLength = postBytes.Length;//设置请求数据的内容长度
using (Stream outstream = request.GetRequestStream())//发送请求
{
outstream.Write(postBytes, 0, postBytes.Length);//将上面的字节写入当前流
}
using (WebResponse response = request.GetResponse())
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())//发送请求
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();//获取请求结果
}
}
}
}
}
catch (Exception ex)
{
Utils.WriteTxt("post发送请求体异常 ex:" + ex.Message + ",StackTrace:" + ex.StackTrace);
}
return result;
}
}
}