diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientEventExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientEventExtensions.cs index 5f42e049..0512fef7 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientEventExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientEventExtensions.cs @@ -12,6 +12,28 @@ namespace SKIT.FlurlHttpClient.Wechat.Api /// public static partial class WechatApiClientEventExtensions { + /// + /// 从 JSON 解析并解密得到明文回调通知事件内容。 + /// + /// + /// + /// + public static string DecryptEventFromJson(this WechatApiClient client, string webhookJson) + { + return InnerDecryptEventFromJson(client, webhookJson); + } + + /// + /// 从 XML 解析并解密明文回调通知事件内容。 + /// + /// + /// + /// + public static string DecryptEventFromXml(this WechatApiClient client, string webhookXml) + { + return InnerDecryptEventFromXml(client, webhookXml); + } + /// /// 从 JSON 反序列化得到 对象。 /// @@ -331,16 +353,9 @@ namespace SKIT.FlurlHttpClient.Wechat.Api try { - if (webhookJson.Contains("\"Encrypt\"")) - { - if (string.IsNullOrEmpty(client.Credentials.PushEncodingAESKey)) - throw new WechatApiException("Failed to decrypt event data, because the push no encoding AES key is not set."); + var webhookJsonString = InnerDecryptEventFromJson(client, webhookJson); - InnerEncryptedEvent encryptedEvent = client.JsonSerializer.Deserialize(webhookJson); - webhookJson = Utilities.WxMsgCryptor.AESDecrypt(cipherText: encryptedEvent.EncryptedData, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _); - } - - return client.JsonSerializer.Deserialize(webhookJson); + return client.JsonSerializer.Deserialize(webhookJsonString); } catch (WechatApiException) { @@ -354,6 +369,56 @@ namespace SKIT.FlurlHttpClient.Wechat.Api private static TEvent InnerDeserializeEventFromXml(WechatApiClient client, string webhookXml) where TEvent : WechatApiEvent + { + + try + { + var webhookXmlString = InnerDecryptEventFromXml(client, webhookXml); + return (TEvent)_XmlSimpleSerializer.Deserialize(webhookXmlString, typeof(TEvent)); + } + catch (ArgumentNullException) + { + throw; + } + catch (WechatApiException) + { + throw; + } + catch (Exception ex) + { + throw new WechatApiException("Failed to deserialize event data. Please see the inner exception for more details.", ex); + } + } + + private static string InnerDecryptEventFromJson(WechatApiClient client, string webhookJson) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (webhookJson is null) throw new ArgumentNullException(webhookJson); + + try + { + if (webhookJson.Contains("\"Encrypt\"")) + { + if (string.IsNullOrEmpty(client.Credentials.PushEncodingAESKey)) + throw new WechatApiException("Failed to decrypt event data, because the push no encoding AES key is not set."); + + InnerEncryptedEvent encryptedEvent = client.JsonSerializer.Deserialize(webhookJson); + webhookJson = Utilities.WxMsgCryptor.AESDecrypt(cipherText: encryptedEvent.EncryptedData, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _); + } + + return webhookJson; + } + catch (WechatApiException) + { + throw; + } + catch (Exception ex) + { + throw new WechatApiException("Failed to deserialize event data. Please see the inner exception for more details.", ex); + } + } + + private static string InnerDecryptEventFromXml(WechatApiClient client, string webhookXml) { if (client is null) throw new ArgumentNullException(nameof(client)); if (webhookXml is null) throw new ArgumentNullException(webhookXml); @@ -368,7 +433,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api webhookXml = Utilities.WxMsgCryptor.AESDecrypt(cipherText: encryptedXml, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _); } - return (TEvent)_XmlSimpleSerializer.Deserialize(webhookXml, typeof(TEvent)); + return webhookXml; } catch (WechatApiException) {