Home >Backend Development >C#.Net Tutorial >C# Development of WeChat Portal and Application (4) Followed User List and Detailed Information Management

C# Development of WeChat Portal and Application (4) Followed User List and Detailed Information Management

黄舟
黄舟Original
2017-06-18 10:28:571574browse

This article mainly introduces the fourth article of C# development of WeChat portal and application in detail, focusing on user list and detailed information management. It has certain reference value. Interested friends can refer to it

Last month I introduced the development of WeChat portals and applications in C#, and wrote several essays to share. Due to time constraints, I have not continued to write this series of blogs for a while. I am not stopping on this aspect. Instead of doing research, we will continue to explore this technology in depth and focus on the underlying technology development for better application.

A very important feature of WeChat is that it can take advantage of the huge user base of its platform, so it is easy to integrate into the CRM (Customer Relationship Management) system. Both service accounts and subscriptions can push relevant information to followers. Product news, and interactive conversations with active users who responded to messages and events within 48 hours. Therefore, user information is a very important part of the WeChat API. This essay mainly introduces how to obtain following users, view user information, group management, etc. Develop applications.

1. Following user list and user group information

On the WeChat management platform, we can see the follower users of our account and user group information. As follows.

In the above management interface, you can see the basic information of follower users, but what you get using the WeChat API is a list called OpenID. Let’s understand this first. What is the thing? The description of the WeChat API gives the following analysis:

The follower list consists of a string of OpenIDs (encrypted WeChat IDs). Each user’s OpenID for each public account is unique. For different public accounts, the same The user's openid is different). Official accounts can use this interface to obtain basic user information based on OpenID, including nickname, avatar, gender, city, language and follow time.

The meaning of the above analysis is very clear, that is, if a user follows our official account, no matter how many times he follows it, it is a certain value for our official account; however, a user For other public accounts, they have different OpenIDs.

WeChat provides a few keyword information to record user-related content. Based on the user's relevant definitions, we define an entity class to place the retrieved user information.


 /// <summary>
 /// 高级接口获取的用户信息。
 /// 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID
 /// (加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。
 /// 公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。
 /// </summary>
 public class UserJson : BaseJsonResult
 {
 /// <summary>
 /// 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
 /// </summary>
 public int subscribe { get; set; }

 /// <summary>
 /// 用户的标识,对当前公众号唯一
 /// </summary>
 public string openid { get; set; }

 /// <summary>
 /// 用户的昵称
 /// </summary>
 public string nickname { get; set; }

 /// <summary>
 /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
 /// </summary>
 public int sex { get; set; }

 /// <summary>
 /// 用户的语言,简体中文为zh_CN
 /// </summary>
 public string language { get; set; }

 /// <summary>
 /// 用户所在城市
 /// </summary>
 public string city { get; set; }

 /// <summary>
 /// 用户所在省份
 /// </summary>
 public string province { get; set; }

 /// <summary>
 /// 用户所在国家
 /// </summary>
 public string country { get; set; }

 /// <summary>
 /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
 /// </summary>
 public string headimgurl { get; set; }

 /// <summary>
 /// 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
 /// </summary>
 public long subscribe_time { get; set; }
 }

According to the grouping information definition, we define a grouped entity class information.


 /// <summary>
 /// 分组信息
 /// </summary>
 public class GroupJson : BaseJsonResult
 {
 /// <summary>
 /// 分组id,由微信分配
 /// </summary>
 public int id { get; set; }

 /// <summary>
 /// 分组名字,UTF8编码
 /// </summary>
 public string name { get; set; }
 }

2. Obtain the Token of the AIP caller

When developing WeChat API, many times we need Pass in an AccessToken, which is a string that distinguishes the caller and records session information. Therefore, before learning all API development, we need to have a good understanding of this Access Control parameter.

#We can understand the definition of this object from WeChat’s API description.

access_token is the globally unique ticket of the public account. The public account needs to use access_token when calling each interface. Under normal circumstances, the access_token is valid for 7200 seconds. Repeated acquisition will cause the last access_token to become invalid. Since the number of api calls to obtain access_token is very limited, it is recommended that developers store and update access_token globally. Frequent refresh of access_token will limit api calls and affect their own business.

According to the above definition, we can see that it is a parameter related to identity and session time, and the number of times it can be generated is limited, so we need to cache it. And reuse, before the session expires, we should reuse this parameter as much as possible to avoid repeated requests, increase server pressure, and call time.

I have defined a method to construct and generate related Access Token, and it has the function of caching, but how to cache and use it is transparent to my API call. As long as we use it, Just call it.


 /// 获取凭证接口
 /// </summary>
 /// <param name="appid">第三方用户唯一凭证</param>
 /// <param name="secret">第三方用户唯一凭证密钥,既appsecret</param>
 string GetAccessToken(string appid, string secret);

The cache is mainly based on the class library MemoryCache added by .NET4. This is a very good cache class.

My operation implementation code for obtaining AccessToken is as follows.


 /// <summary>
 /// 获取每次操作微信API的Token访问令牌
 /// </summary>
 /// <param name="appid">应用ID</param>
 /// <param name="secret">开发者凭据</param>
 /// <returns></returns>
 public string GetAccessToken(string appid, string secret)
 {
  //正常情况下access_token有效期为7200秒,这里使用缓存设置短于这个时间即可
  string access_token = MemoryCacheHelper.GetCacheItem<string>("access_token", delegate()
  {
   string grant_type = "client_credential";
   var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}",
      grant_type, appid, secret);

   HttpHelper helper = new HttpHelper();
   string result = helper.GetHtml(url);
   string regex = "\"access_token\":\"(?<token>.*?)\"";
   string token = CRegex.GetText(result, regex, "token");
   return token;
  },
  new TimeSpan(0, 0, 7000)//7000秒过期
  );

  return access_token;  
 }

Since we know that AccessToken expires in 7200 seconds by default, so within this time period, we use cache as much as possible to record its value. If this time is exceeded, , when we call this method, it will automatically obtain a new value for us.

3. Get the list of following users

Get the list of following users. One pull API call can pull up to 10,000 followers' OpenIDs. You can pull them multiple times. ways to meet needs. The interface definition of WeChat is as follows.

http请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

这个接口返回的数据是


{"total":2,"count":2,"data":{"openid":["","OPENID1","OPENID2"]},"next_openid":"NEXT_OPENID"}

根据返回的Json数据定义,我们还需要定义两个实体类,用来存放返回的结果。


 /// <summary>
 /// 获取关注用户列表的Json结果
 /// </summary>
 public class UserListJsonResult : BaseJsonResult
 {
 /// <summary>
 /// 关注该公众账号的总用户数
 /// </summary>
 public int total { get; set; }

 /// <summary>
 /// 拉取的OPENID个数,最大值为10000
 /// </summary>
 public int count { get; set; }

 /// <summary>
 /// 列表数据,OPENID的列表
 /// </summary>
 public OpenIdListData data { get; set; }

 /// <summary>
 /// 拉取列表的后一个用户的OPENID
 /// </summary>
 public string next_openid { get; set; }
 }

 /// <summary>
 /// 列表数据,OPENID的列表
 /// </summary>
 public class OpenIdListData
 {
 /// <summary>
 /// OPENID的列表
 /// </summary>
 public List<string> openid { get; set; }
 }

为了获取相关的用户信息,我定义了一个接口,用来获取用户的信息,接口定义如下所示。


 /// <summary>
 /// 微信用户管理的API接口
 /// </summary>
 public interface IUserApi
 {
 /// <summary>
 /// 获取关注用户列表
 /// </summary>
 /// <param name="accessToken">调用接口凭证</param>
 /// <param name="nextOpenId">第一个拉取的OPENID,不填默认从头开始拉取</param>
 /// <returns></returns>
 List<string> GetUserList(string accessToken, string nextOpenId = null);

 /// <summary>
 /// 获取用户基本信息
 /// </summary>
 /// <param name="accessToken">调用接口凭证</param>
 /// <param name="openId">普通用户的标识,对当前公众号唯一</param>
 /// <param name="lang">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param>
 UserJson GetUserDetail(string accessToken, string openId, Language lang = Language.zh_CN);

然后在实现类里面,我们分别对上面两个接口进行实现,获取用户列表信息如下所示。


 /// <summary>
 /// 获取关注用户列表
 /// </summary>
 /// <param name="accessToken">调用接口凭证</param>
 /// <param name="nextOpenId">第一个拉取的OPENID,不填默认从头开始拉取</param>
 /// <returns></returns>
 public List<string> GetUserList(string accessToken, string nextOpenId = null)
 {
  List<string> list = new List<string>();

  string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}", accessToken);
  if (!string.IsNullOrEmpty(nextOpenId))
  {
  url += "&next_openid=" + nextOpenId;
  }

  UserListJsonResult result = JsonHelper<UserListJsonResult>.ConvertJson(url);
  if (result != null && result.data != null)
  {
  list.AddRange(result.data.openid);
  }

  return list;
 }

我们看到,转换的逻辑已经放到了JsonHelper里面去了,这个辅助类里面分别对数值进行了获取内容,验证返回值,然后转换正确实体类几个部分的操作。

获取内容,通过辅助类HttpHelper进行,这个在我的公用类库里面,里面的逻辑主要就是通过HttpRequest进行数据的获取操作,不在赘述。


HttpHelper helper = new HttpHelper();
string content = helper.GetHtml(url);

由于返回的内容,我们需要判断它是否正确返回所需的结果,如果没有,抛出自定义的相关异常,方便处理,具体如下所示。


 /// <summary>
 /// 检查返回的记录,如果返回没有错误,或者结果提示成功,则不抛出异常
 /// </summary>
 /// <param name="content">返回的结果</param>
 /// <returns></returns>
 private static bool VerifyErrorCode(string content)
 {
  if (content.Contains("errcode"))
  {
  ErrorJsonResult errorResult = JsonConvert.DeserializeObject<ErrorJsonResult>(content);
  //非成功操作才记录异常,因为有些操作是返回正常的结果({"errcode": 0, "errmsg": "ok"})
  if (errorResult != null && errorResult.errcode != ReturnCode.请求成功)
  {
   string error = string.Format("微信请求发生错误!错误代码:{0},说明:{1}", (int)errorResult.errcode, errorResult.errmsg);
   LogTextHelper.Error(errorResult);

   throw new WeixinException(error);//抛出错误
  }
  }
  return true;
 }

然后转换为相应的格式,就是通过Json.NET的类库进行转换。


T result = JsonConvert.DeserializeObject<T>(content);
return result;

这样我们就可以在ConvertJson函数实体里面,完整的进行处理和转换了,转换完整的函数代码如下所示。


 /// 
 /// Json字符串操作辅助类
 /// 
 public class JsonHelper where T : class, new()
 {
 /// <summary>
 /// 检查返回的记录,如果返回没有错误,或者结果提示成功,则不抛出异常
 /// </summary>
 /// <param name="content">返回的结果</param>
 /// <returns></returns>
 private static bool VerifyErrorCode(string content)
 {
  if (content.Contains("errcode"))
  {
  ErrorJsonResult errorResult = JsonConvert.DeserializeObject<ErrorJsonResult>(content);
  //非成功操作才记录异常,因为有些操作是返回正常的结果({"errcode": 0, "errmsg": "ok"})
  if (errorResult != null && errorResult.errcode != ReturnCode.请求成功)
  {
   string error = string.Format("微信请求发生错误!错误代码:{0},说明:{1}", (int)errorResult.errcode, errorResult.errmsg);
   LogTextHelper.Error(errorResult);

   throw new WeixinException(error);//抛出错误
  }
  }
  return true;
 }

 /// 
 /// 转换Json字符串到具体的对象
 /// 
 /// 返回Json数据的链接地址
 /// 
 public static T ConvertJson(string url)
 {
  HttpHelper helper = new HttpHelper();
  string content = helper.GetHtml(url);
  VerifyErrorCode(content);

  T result = JsonConvert.DeserializeObject(content);
  return result;
 }
}

调用这个API的界面层代码如下所示(测试代码)


 IUserApi userBLL = new UserApi();
 List<string> userList = userBLL.GetUserList(token)

4、获取用户详细信息

上面的获取列表操作,相对比较简单,而且不用POST任何数据,因此通过Get协议就能获取到所需的数据。

本小节继续介绍获取用户详细信息的操作,这个操作也是通过GET协议就可以完成的。

这个API的调用定义如下所示:

http请求方式: GET
api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
通过传入一个OpenId,我们就能很好获取到用户的相关信息了。

前面小节我们已经定义了它的接口,说明了传入及返回值,根据定义,它的实现函数如下所示。

 /// <summary>
 /// 获取用户基本信息
 /// </summary>
 /// <param name="accessToken">调用接口凭证</param>
 /// <param name="openId">普通用户的标识,对当前公众号唯一</param>
 /// <param name="lang">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param>
 public UserJson GetUserDetail(string accessToken, string openId, Language lang = Language.zh_CN)
 {
  string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang={2}",
   accessToken, openId, lang.ToString());

  UserJson result = JsonHelper<UserJson>.ConvertJson(url);
  return result;
 }

最后,我们结合获取用户列表和获取用户详细信息的两个API,我们看看调用的代码(测试代码)。


 private void btnGetUsers_Click(object sender, EventArgs e)
 {
  IUserApi userBLL = new UserApi();
  List<string> userList = userBLL.GetUserList(token);
  foreach (string openId in userList)
  {
  UserJson userInfo = userBLL.GetUserDetail(token, openId);
  if (userInfo != null)
  {   
   string tips = string.Format("{0}:{1}", userInfo.nickname, userInfo.openid);
   Console.WriteLine(tips);
  }
  }
 }

The above is the detailed content of C# Development of WeChat Portal and Application (4) Followed User List and Detailed Information Management. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn