本次更新同时影响以下所有Senparc.Weixin相关版本的dll:

  • Senparc.Weixin.dll 升级到 v4.4.2(重要)
  • Senparc.Weixin.MP.dll 升级到 v13.4.0(重要)
  • Senparc.Weixin.MP.MvcExtension.dll 无需升级
  • Senparc.Weixin.Open 升级到 v1.5.3(重要)
  • Senparc.Weixin.QY.dll 升级到 v3.2.0(重要)

  源代码:https://github.com/JeffreySu/WeiXinMPSDK

  Demo:http://weixin.senparc.com/

  Nuget:

  本次更新重构了Senparc.Weixin整个框架内几乎所有的CommonJsonSend类,并且为SDK添加了Debug状态用于调试状态下自动输出日志,以及其他异常类型相关的升级。

  具体升级内容如下:

Senparc.Weixin.dll

  1. 添加WeixinTrace类,用于输出完整的API请求等日志。

     /*----------------------------------------------------------------
    Copyright (C) 2015 Senparc 文件名:WeixinTrace.cs
    文件功能描述:跟踪日志相关 创建标识:Senparc - 20151012 ----------------------------------------------------------------*/ using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Senparc.Weixin.Exceptions; namespace Senparc.Weixin
    {
    /// <summary>
    /// 微信日志跟踪
    /// </summary>
    public static class WeixinTrace
    {
    private static TraceListener _traceListener = null;
    private static readonly object TraceLock = new object(); internal static void Open()
    {
    Close();
    lock (TraceLock)
    {
    var logDir = System.AppDomain.CurrentDomain.BaseDirectory + "App_Data";
    string logFile = Path.Combine(logDir, "SenparcWeixinTrace.log");
    System.IO.TextWriter logWriter = new System.IO.StreamWriter(logFile, true);
    _traceListener = new TextWriterTraceListener(logWriter);
    System.Diagnostics.Trace.Listeners.Add(_traceListener);
    System.Diagnostics.Trace.AutoFlush = true;
    }
    } internal static void Close()
    {
    lock (TraceLock)
    {
    if (_traceListener != null && System.Diagnostics.Trace.Listeners.Contains(_traceListener))
    {
    _traceListener.Close();
    System.Diagnostics.Trace.Listeners.Remove(_traceListener);
    }
    }
    } /// <summary>
    /// 统一时间格式
    /// </summary>
    private static void TimeLog()
    {
    Log(string.Format("[{0}]", DateTime.Now));
    } private static void Unindent()
    {
    lock (TraceLock)
    {
    System.Diagnostics.Trace.Unindent();
    }
    } private static void Indent()
    {
    lock (TraceLock)
    {
    System.Diagnostics.Trace.Indent();
    }
    } private static void Flush()
    {
    lock (TraceLock)
    {
    System.Diagnostics.Trace.Flush();
    }
    } private static void LogBegin(string title = null)
    {
    Open();
    Log(title == null ? "" : String.Format("[{0}]", title));
    TimeLog();
    Indent();
    } /// <summary>
    /// 记录日志
    /// </summary>
    /// <param name="message"></param>
    public static void Log(string message)
    {
    lock (TraceLock)
    {
    System.Diagnostics.Trace.WriteLine(message);
    }
    } private static void LogEnd()
    {
    Unindent();
    Flush();
    Close();
    } /// <summary>
    /// API请求日志
    /// </summary>
    /// <param name="url"></param>
    /// <param name="returnText"></param>
    public static void SendLog(string url, string returnText)
    {
    if (!Config.IsDebug)
    {
    return;
    } LogBegin("接口调用");
    Log(string.Format("URL:{0}", url));
    Log(string.Format("Result:\r\n{0}", returnText));
    LogEnd();
    } /// <summary>
    /// ErrorJsonResultException 日志
    /// </summary>
    /// <param name="ex"></param>
    public static void ErrorJsonResultExceptionLog(ErrorJsonResultException ex)
    {
    if (!Config.IsDebug)
    {
    return;
    } LogBegin("ErrorJsonResultException");
    Log(string.Format("URL:{0}", ex.Url));
    Log(string.Format("errcode:{0}", ex.JsonResult.errcode));
    Log(string.Format("errmsg:{0}", ex.JsonResult.errmsg));
    LogEnd();
    }
    }
    }

    在WeixinTrace中,已经提供了两个自带的日志记录方法,供SDK的扩展库使用:

    • SendLog():API请求日志
      日志格式如下:

      [接口调用]
      [2015/10/14 10:40:27]
      URL:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=-3w2HMV7R1r_YWAryHtoVDzOHffPUUe4Cf48
      Result:
      {"errcode":0,"errmsg":"ok"}

    • ErrorJsonResultExceptionLog():每次创建ErrorJsonResultException的时候记录该异常的信息
      日志格式如下:

      [ErrorJsonResultException]
      [2015/10/14 11:13:49]
      URL:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=[AppId]&secret=[AppSecret]
      errcode:获取access_token时AppSecret错误或者access_token无效
      errmsg:invalid credential, access_token is invalid or not latest hint: [weMY8a0430vr18]

    这些日志默认被记录在网站(或应用)的App_Data/SenparcWeixinTrace.log文件中。

    日志只有在SDK出于Debug状态下才会记录,如何开启Debug状态请看下面。

  2. 添加Config.IsDebug属性。当Config.IsDebug为true时,WeixinTrace的日志记录功能才会被开启,否则即使调用方法,日志也不会被记录。
    建议在调试阶段使用此功能,正式发布的时候关闭。Debug状态可以在程序启动的时候或程序中的任意位置执行,如:
    namespace Senparc.Weixin.MP.Sample
    {
    public class WebApiApplication : System.Web.HttpApplication
    {
    protected void Application_Start()
    {
    //...
    Senparc.Weixin.Config.IsDebug = true;//这里设为Debug状态时,/App_Data/目录下会生成日志文件记录所有的API请求日志,正式发布版本建议关闭
    }
    }
    }

    或者像这样在管理员权限下面(建议)做一个开关:

    namespace Senparc.Weixin.MP.Sample.Controllers
    {
    public class HomeController : BaseController
    {
    public ActionResult DebugOpen()
    {
    Senparc.Weixin.Config.IsDebug = true;
    return Content("Debug状态已打开。");
    } public ActionResult DebugClose()
    {
    Senparc.Weixin.Config.IsDebug = false;
    return Content("Debug状态已关闭。");
    }
    }
    }
  3. 添加CommonAPIs/CommonJsonSend.cs,旧版本的Senparc.Weixin.MP及Senparc.Weixin.Open对应文件删除,统一到Senparc.Weixin中。

    .net 4.5版本的代码如下(.net 4.0版本没有异步功能):
    /*----------------------------------------------------------------
    Copyright (C) 2015 Senparc 文件名:CommonJsonSend.cs
    文件功能描述:通过CommonJsonSend中的方法调用接口 创建标识:Senparc - 20151012 ----------------------------------------------------------------*/ using System;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Senparc.Weixin.Entities;
    using Senparc.Weixin.Exceptions;
    using Senparc.Weixin.Helpers;
    using Senparc.Weixin.HttpUtility; namespace Senparc.Weixin.CommonAPIs
    {
    /// <summary>
    /// CommonJsonSend
    /// </summary>
    public static class CommonJsonSend
    {
    #region 同步请求 /// <summary>
    /// 向需要AccessToken的API发送消息的公共方法
    /// </summary>
    /// <param name="accessToken">这里的AccessToken是通用接口的AccessToken,非OAuth的。如果不需要,可以为null,此时urlFormat不要提供{0}参数</param>
    /// <param name="urlFormat"></param>
    /// <param name="data">如果是Get方式,可以为null</param>
    /// <param name="sendType"></param>
    /// <param name="timeOut">代理请求超时时间(毫秒)</param>
    /// <param name="jsonSetting"></param>
    /// <returns></returns>
    public static WxJsonResult Send(string accessToken, string urlFormat, object data, CommonJsonSendType sendType = CommonJsonSendType.POST, int timeOut = Config.TIME_OUT, bool checkValidationResult = false, JsonSetting jsonSetting = null)
    {
    return Send<WxJsonResult>(accessToken, urlFormat, data, sendType, timeOut);
    } /// <summary>
    /// 向需要AccessToken的API发送消息的公共方法
    /// </summary>
    /// <param name="accessToken">这里的AccessToken是通用接口的AccessToken,非OAuth的。如果不需要,可以为null,此时urlFormat不要提供{0}参数</param>
    /// <param name="urlFormat">用accessToken参数填充{0}</param>
    /// <param name="data">如果是Get方式,可以为null</param>
    /// <param name="sendType"></param>
    /// <param name="timeOut">代理请求超时时间(毫秒)</param>
    /// <param name="checkValidationResult"></param>
    /// <param name="jsonSetting"></param>
    /// <returns></returns>
    public static T Send<T>(string accessToken, string urlFormat, object data, CommonJsonSendType sendType = CommonJsonSendType.POST, int timeOut = Config.TIME_OUT, bool checkValidationResult = false, JsonSetting jsonSetting = null)
    {
    //TODO:此方法可以设定一个日志记录开关 try
    {
    var url = string.IsNullOrEmpty(accessToken) ? urlFormat : string.Format(urlFormat, accessToken);
    switch (sendType)
    {
    case CommonJsonSendType.GET:
    return Get.GetJson<T>(url);
    case CommonJsonSendType.POST:
    SerializerHelper serializerHelper = new SerializerHelper();
    var jsonString = serializerHelper.GetJsonString(data);
    using (MemoryStream ms = new MemoryStream())
    {
    var bytes = Encoding.UTF8.GetBytes(jsonString);
    ms.Write(bytes, , bytes.Length);
    ms.Seek(, SeekOrigin.Begin); return Post.PostGetJson<T>(url, null, ms, timeOut: timeOut, checkValidationResult: checkValidationResult);
    } //TODO:对于特定的错误类型自动进行一次重试,如40001(目前的问题是同样40001会出现在不同的情况下面)
    default:
    throw new ArgumentOutOfRangeException("sendType");
    }
    }
    catch (ErrorJsonResultException ex)
    {
    ex.Url = urlFormat;
    throw;
    }
    } #endregion #region 异步请求 /// <summary>
    /// 向需要AccessToken的API发送消息的公共方法
    /// </summary>
    /// <param name="accessToken">这里的AccessToken是通用接口的AccessToken,非OAuth的。如果不需要,可以为null,此时urlFormat不要提供{0}参数</param>
    /// <param name="urlFormat"></param>
    /// <param name="data">如果是Get方式,可以为null</param>
    /// <param name="timeOut">代理请求超时时间(毫秒)</param>
    /// <returns></returns>
    public static async Task<WxJsonResult> SendAsync(string accessToken, string urlFormat, object data, CommonJsonSendType sendType = CommonJsonSendType.POST, int timeOut = Config.TIME_OUT)
    {
    return await SendAsync<WxJsonResult>(accessToken, urlFormat, data, sendType, timeOut);
    } /// <summary>
    /// 向需要AccessToken的API发送消息的公共方法
    /// </summary>
    /// <param name="accessToken">这里的AccessToken是通用接口的AccessToken,非OAuth的。如果不需要,可以为null,此时urlFormat不要提供{0}参数</param>
    /// <param name="urlFormat"></param>
    /// <param name="data">如果是Get方式,可以为null。在POST方式中将被转为JSON字符串提交</param>
    /// <param name="sendType">发送类型,POST或GET,默认为POST</param>
    /// <param name="timeOut">代理请求超时时间(毫秒)</param>
    /// <param name="checkValidationResult">验证服务器证书回调自动验证</param>
    /// <param name="jsonSetting">JSON字符串生成设置</param>
    /// <returns></returns>
    public static async Task<T> SendAsync<T>(string accessToken, string urlFormat, object data, CommonJsonSendType sendType = CommonJsonSendType.POST, int timeOut = Config.TIME_OUT, bool checkValidationResult = false,
    JsonSetting jsonSetting = null
    )
    {
    try
    {
    var url = string.IsNullOrEmpty(accessToken) ? urlFormat : string.Format(urlFormat, accessToken); switch (sendType)
    {
    case CommonJsonSendType.GET:
    return await Get.GetJsonAsync<T>(url);
    case CommonJsonSendType.POST:
    SerializerHelper serializerHelper = new SerializerHelper();
    var jsonString = serializerHelper.GetJsonString(data, jsonSetting);
    using (MemoryStream ms = new MemoryStream())
    {
    var bytes = Encoding.UTF8.GetBytes(jsonString);
    await ms.WriteAsync(bytes, , bytes.Length);
    ms.Seek(, SeekOrigin.Begin); return
    await
    Post.PostGetJsonAsync<T>(url, null, ms, timeOut: timeOut,
    checkValidationResult: checkValidationResult);
    }
    default:
    throw new ArgumentOutOfRangeException("sendType");
    }
    }
    catch (ErrorJsonResultException ex)
    {
    ex.Url = urlFormat;
    throw;
    }
    } #endregion
    }
    }
  4. 修改ErrorJsonResultException类,添加Url属性,方便开发者跟踪异常来自哪个URL(通常是请求接口)。
     /*----------------------------------------------------------------
    Copyright (C) 2015 Senparc 文件名:ErrorJsonResultException.cs
    文件功能描述:JSON返回错误代码(比如token_access相关操作中使用)。 创建标识:Senparc - 20150211 修改标识:Senparc - 20150303
    修改描述:整理接口
    ----------------------------------------------------------------*/ using System;
    using Senparc.Weixin.Entities; namespace Senparc.Weixin.Exceptions
    {
    /// <summary>
    /// JSON返回错误代码(比如token_access相关操作中使用)。
    /// </summary>
    public class ErrorJsonResultException : WeixinException
    {
    public WxJsonResult JsonResult { get; set; }
    public string Url { get; set; } /// <summary>
    ///
    /// </summary>
    /// <param name="message"></param>
    /// <param name="inner"></param>
    /// <param name="jsonResult"></param>
    /// <param name="url"></param>
    public ErrorJsonResultException(string message, Exception inner, WxJsonResult jsonResult, string url = null)
    : base(message, inner)
    {
    JsonResult = jsonResult;
    Url = url; WeixinTrace.ErrorJsonResultExceptionLog(this);
    }
    }
    }

Senparc.Weixin.MP.dll

  1. 弃用CommonJsonSend类(如果还继续使用不会出错,编译时候会提示过期),将在今后版本中彻底删除。
  2. 优化JsSdkApi相关接口。

Senparc.Weixin.Open.dll

  1. 弃用CommonJsonSend类(如果还继续使用不会出错,编译时候会提示过期),将在今后版本中彻底删除。
  2. 完善ComponentContainer及ComponentApi下的接口。
  3. 完善Component及OAuth相关接口,提供了更加自动化的接口获取。
  4. 比如以前按照官方的流程我们需要走4步才可以获取到queryAuth的授权(微信官方文档:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318587&token=f6aa7cd0d4ffc0820a9d694daa06fb841123fd2e&lang=zh_CN):
                     string openTicket = OpenTicketHelper.GetOpenTicket(component_AppId);
    var component_access_token = Open.CommonAPIs.CommonApi.GetComponentAccessToken(component_AppId, component_Secret, openTicket).component_access_token;
    ComponentAccessToken = component_access_token;
    var oauthResult = Open.ComponentAPIs.ComponentApi.QueryAuth(component_access_token, component_AppId, auth_code);

    现在有了ComponentContainer,只需要一步,整个过程(包括所有会过期的token,ComponentContainer都会自动管理):

                     var queryAuthResult = ComponentContainer.GetQueryAuthResult(component_AppId, auth_code);

    还有比这个更爽的吗?
    Sample中的Demo也已经同步更新,大家现在可以在这个页面打开测试:http://weixin.senparc.com/OpenOAuth/JumpToMpOAuth

Senparc.Weixin.QY.dll

  常规升级,由于企业号的错误类型等,和公众号、开放平台不一样,所以本次更新没有将企业号的CommonJsonSend集结到Senparc.Weixin.dll中,仍然独立存在。

  系列教程索引:http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html

【重要更新】Senparc.Weixin SDK v4.4 升级说明的更多相关文章

  1. 【重要更新】Senparc.Weixin SDK v4.3.3升级说明

    为了更好地适应微信越来越快的API更新速度和越来越多的API数量,本次Senparc.Weixin.dll v4.3.3对一些通用功能进行了深度的重构. 本次更新同时影响以下所有Senparc.Wei ...

  2. 【重要更新】Senparc.Weixin SDK v6.5 升级说明(支持 .NET Core 3.0 及分布式消息上下文)

    Senparc.Weixin SDK v6.5 开始支持 .NET Core 3.0,并将微信消息上下文进行了大幅度的重构,支持了使用分布式缓存存储上下文信息,这意味着在分布式系统中,现在 Senpa ...

  3. Senparc.Weixin SDK v5.0 升级公告

    经过五年半的持续维护,Senparc.Weixin SDK 逐步丰满和完善,在升级的过程中,我们为基础库(Senparc.Weixin.dll)加入了许多通用的功能,例如加密/解密算法.通用缓存方法等 ...

  4. Senparc.Weixin SDK 微信公众号 .NET 开发教程 索引

    Senparc.WeixinSDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到比较稳定的版本,这个过程中我觉得有必要整理一些思路和经验,和大家一起分享.也欢迎大 ...

  5. 利用Senparc.Weixin SDK 实现微信用户的授权,并获取信息

    前一段时间在学校做过一个项目,就是利用的Senparc.Weixin SDK 做的,于是翻看以前代码,虽然有注释,但是还是看的迷迷糊糊的,干脆就单步执行一遍看看是怎么实现的,然后就重新写了个简易的授权 ...

  6. 如何使用Senparc.Weixin SDK 底层的Redis缓存并设置过期时间

    最近在微信第三方平台项目开发中,有一个需求,所有绑定的公众号的回复规则按照主公众号的关键词配置来处理,我的处理思路是获取主公众号配置的关键词回复规则,缓存10分钟,由于需要使用Redis缓存来存储一些 ...

  7. 微信公众账号 Senparc.Weixin.MP SDK 开发教程 索引

    Senparc.Weixin.MP SDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到比较稳定的版本,这个过程中我觉得有必要整理一些思路和经验,和大家一起分享. ...

  8. 微信公众平台C# SDK:Senparc.Weixin.MP.dll

    https://github.com/Senparc/WeiXinMPSDK [转] http://www.cnblogs.com/szw/archive/2013/01/13/senparc-wei ...

  9. Senparc.Weixin.MP SDK 微信公众平台开发教程(十七):个性化菜单接口说明

    前不久微信上线了个性化菜单接口,Senparc.Weixin SDK也已经同步更新. 本次更新升级Senparc.Weixin.MP版本到v13.5.2,依赖Senparc.Weixin版本4.5.4 ...

随机推荐

  1. eclipse生成uml

    安装eclipse插件在help->Install new software里面add 有本地和网络两种 1.ModelGoon 该插件需要在file中new ModelGoon Diagram ...

  2. bash快捷建

    bash快捷建 ctrl键组合ctrl+a:光标移到行首.ctrl+b:光标左移一个字母ctrl+c:杀死当前进程.ctrl+d:退出当前 Shell.ctrl+e:光标移到行尾.ctrl+h:删除光 ...

  3. Android 时间维护服务 TimeService(针对于特殊定制设备)

    此方法针对于无法自动获取网络时间的特殊设备,正常 Android 设备直接调用 System.currentTimeMillis(); 方法获取当前时间即可. TimeService 集成于 Serv ...

  4. 使用xtrabackup备份mysql数据库

    数据在一个企业里非常重要,因此经常需要备份数据库,确保出线故障时,可以立刻恢复数据到最新状态,目前常见的备份工具有mysqldump和xtrabackup,数据量较少时可以使用mysqldump,但随 ...

  5. GDB常用命令

    一. gdb使用流程 1.编译生成可执行文件 gcc -g hello.c -o hello 2.启动gdb gdb hello 3. 在main处设置断点 break main 4.运行程序 run ...

  6. IIS7 应用程序池回收

    原文:http://technet.microsoft.com/zh-cn/library/cc754494 应用到: Windows 7, Windows Server 2008, Windows ...

  7. ubuntu10.04下修改mysql的datadir的问题

    ubuntu10.04下修改mysql的datadir的问题 转自:http://blog.sina.com.cn/s/blog_4152a9f50100mq5i.html 昨天由于服务器空间告紧,需 ...

  8. How to create Web Deployment Package and install the package

    Create Web Deployment Package To configure settings on the Connection tab In the Publish method drop ...

  9. c#实现房贷计算的方法源码

    public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/j ...

  10. Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7497260 更多请看专栏,地址 ...