diff --git a/src/ICanPay.Core/Attributes/ReNameAttribute.cs b/src/ICanPay.Core/Attributes/ReNameAttribute.cs
new file mode 100644
index 0000000..d8f147e
--- /dev/null
+++ b/src/ICanPay.Core/Attributes/ReNameAttribute.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace ICanPay.Core
+{
+ ///
+ /// 重命名属性
+ ///
+ public class ReNameAttribute : Attribute
+ {
+ public string Name { get; set; }
+
+ public ReNameAttribute()
+ {
+ }
+ }
+}
diff --git a/src/ICanPay.Core/Gateways/GatewayBase.cs b/src/ICanPay.Core/Gateways/GatewayBase.cs
index 5212d4e..c05f54a 100644
--- a/src/ICanPay.Core/Gateways/GatewayBase.cs
+++ b/src/ICanPay.Core/Gateways/GatewayBase.cs
@@ -178,42 +178,6 @@ namespace ICanPay.Core
}
}
- ///
- /// ¶Áȡ֪ͨ
- ///
- protected void ReadNotify() where T : INotify
- {
- var type = typeof(T);
- var notify = Activator.CreateInstance(type);
- var properties = type.GetProperties();
-
- foreach (var item in properties)
- {
- string key = item
- .GetCustomAttributesData()[0]
- .NamedArguments[0]
- .TypedValue
- .Value
- .ToString();
- object value = GatewayData.GetValue(key);
-
- if (value != null)
- {
- item.SetValue(notify, Convert.ChangeType(value, item.PropertyType));
- }
- }
-
- Notify = (INotify)notify;
- }
-
- ///
- /// Ò첽¶Áȡ֪ͨ
- ///
- protected async Task ReadNotifyAsync() where T : INotify
- {
- await Task.Run(() => ReadNotify());
- }
-
protected void OnPaymentFailed(PaymentFailedEventArgs e) => PaymentFailed?.Invoke(this, e);
protected void OnPaymentSucceed(PaymentSucceedEventArgs e) => PaymentSucceed?.Invoke(this, e);
diff --git a/src/ICanPay.Core/Gateways/GatewayData.cs b/src/ICanPay.Core/Gateways/GatewayData.cs
index 6e9a72d..17c89d1 100644
--- a/src/ICanPay.Core/Gateways/GatewayData.cs
+++ b/src/ICanPay.Core/Gateways/GatewayData.cs
@@ -54,6 +54,38 @@ namespace ICanPay.Core
return true;
}
+ ///
+ /// 添加参数
+ ///
+ ///
+ public bool Add(object obj)
+ {
+ var type = obj.GetType();
+ var properties = type.GetProperties();
+
+ foreach (var item in properties)
+ {
+ var key = item.Name.ToSnakeCase();
+ var value = item.GetValue(obj);
+
+ if (value is null || string.IsNullOrEmpty(value.ToString()))
+ {
+ continue;
+ }
+
+ if (Exists(key))
+ {
+ Values[key] = value;
+ }
+ else
+ {
+ Values.Add(key, value);
+ }
+ }
+
+ return true;
+ }
+
///
/// 根据参数名获取参数值
///
@@ -362,6 +394,39 @@ namespace ICanPay.Core
}
}
+ ///
+ /// 将网关参数转为类型
+ ///
+ public T ToObject()
+ {
+ var type = typeof(T);
+ var obj = Activator.CreateInstance(type);
+ var properties = type.GetProperties();
+
+ foreach (var item in properties)
+ {
+ string key;
+ var renameAttribute = item.GetCustomAttributes(typeof(ReNameAttribute), true);
+ if (renameAttribute.Count() > 0)
+ {
+ key = ((ReNameAttribute)renameAttribute[0]).Name;
+ }
+ else
+ {
+ key = item.Name.ToSnakeCase();
+ }
+
+ object value = GetValue(key);
+
+ if (value != null)
+ {
+ item.SetValue(obj, Convert.ChangeType(value, item.PropertyType));
+ }
+ }
+
+ return (T)obj;
+ }
+
///
/// 清空网关数据
///
diff --git a/src/ICanPay.Core/Payments/NotifyProcess.cs b/src/ICanPay.Core/Payments/NotifyProcess.cs
index 0b99990..ccc1453 100644
--- a/src/ICanPay.Core/Payments/NotifyProcess.cs
+++ b/src/ICanPay.Core/Payments/NotifyProcess.cs
@@ -113,7 +113,11 @@ namespace ICanPay.Core
}
else
{
- gatewayData.FromForm(HttpUtil.Form);
+ try
+ {
+ gatewayData.FromForm(HttpUtil.Form);
+ }
+ catch { }
}
}
diff --git a/src/ICanPay.Core/Utils/Util.cs b/src/ICanPay.Core/Utils/Util.cs
index 69fa9cf..f9f5c61 100644
--- a/src/ICanPay.Core/Utils/Util.cs
+++ b/src/ICanPay.Core/Utils/Util.cs
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
+using System.Text;
namespace ICanPay.Core
{
@@ -42,6 +43,87 @@ namespace ICanPay.Core
return (int)(time.ToUniversalTime().Ticks / 10000000 - 62135596800);
}
+ #region 字符串策略
+
+ internal enum SnakeCaseState
+ {
+ Start,
+ Lower,
+ Upper,
+ NewWord
+ }
+
+ ///
+ /// 将字符串转换为蛇形策略
+ ///
+ /// 字符串
+ ///
+ public static string ToSnakeCase(this string s)
+ {
+ if (string.IsNullOrEmpty(s))
+ {
+ return s;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ SnakeCaseState state = SnakeCaseState.Start;
+
+ for (int i = 0; i < s.Length; i++)
+ {
+ if (s[i] == ' ')
+ {
+ if (state != SnakeCaseState.Start)
+ {
+ state = SnakeCaseState.NewWord;
+ }
+ }
+ else if (char.IsUpper(s[i]))
+ {
+ switch (state)
+ {
+ case SnakeCaseState.Upper:
+ bool hasNext = (i + 1 < s.Length);
+ if (i > 0 && hasNext)
+ {
+ char nextChar = s[i + 1];
+ if (!char.IsUpper(nextChar) && nextChar != '_')
+ {
+ sb.Append('_');
+ }
+ }
+ break;
+ case SnakeCaseState.Lower:
+ case SnakeCaseState.NewWord:
+ sb.Append('_');
+ break;
+ }
+
+ sb.Append(char.ToLowerInvariant(s[i]));
+
+ state = SnakeCaseState.Upper;
+ }
+ else if (s[i] == '_')
+ {
+ sb.Append('_');
+ state = SnakeCaseState.Start;
+ }
+ else
+ {
+ if (state == SnakeCaseState.NewWord)
+ {
+ sb.Append('_');
+ }
+
+ sb.Append(s[i]);
+ state = SnakeCaseState.Lower;
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ #endregion
+
#endregion
}
}