#if NETCOREAPP3_1 using Microsoft.AspNetCore.Http; #endif using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Net; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PaySharp.Core.Utils; namespace PaySharp.Core { /// /// 网关数据 /// public class GatewayData { #region 私有字段 private readonly SortedDictionary _values; #endregion #region 属性 public object this[string key] { get => _values[key]; set => _values[key] = value; } public SortedDictionary.KeyCollection Keys => _values.Keys; public SortedDictionary.ValueCollection Values => _values.Values; public KeyValuePair this[int index] => _values.ElementAt(index); public int Count => _values.Count; /// /// 原始值 /// public string Raw { get; set; } #endregion #region 构造函数 /// /// 构造函数 /// public GatewayData() { _values = new SortedDictionary(); } /// /// 构造函数 /// /// 排序策略 public GatewayData(IComparer comparer) { _values = new SortedDictionary(comparer); } #endregion #region 方法 /// /// 添加参数 /// /// 参数名 /// 参数值 /// public bool Add(string key, object value) { Raw = null; if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key", "参数名不能为空"); } if (value is null || string.IsNullOrEmpty(value.ToString())) { return false; } if (Exists(key)) { _values[key] = value; } else { _values.Add(key, value); } return true; } /// /// 添加参数 /// /// 对象 /// 字符串策略 /// public bool Add(object obj, StringCase stringCase) { ValidateUtil.Validate(obj, null); Raw = null; var type = obj.GetType(); var properties = type.GetProperties(); var fields = type.GetFields(); Add(obj, properties, stringCase); Add(obj, fields, stringCase); return true; } private void Add(object obj, MemberInfo[] info, StringCase stringCase) { foreach (var item in info) { var notAddattributes = item.GetCustomAttributes(typeof(IgnoreAttribute), true); if (notAddattributes.Length > 0) { continue; } string key; var renameAttribute = item.GetCustomAttributes(typeof(ReNameAttribute), true); if (renameAttribute.Length > 0) { key = ((ReNameAttribute)renameAttribute[0]).Name; } else { key = stringCase switch { StringCase.Snake => item.Name.ToSnakeCase(), StringCase.Camel => item.Name.ToCamelCase(), StringCase.Lower => item.Name.ToLower(), _ => item.Name, }; } var value = item.MemberType switch { MemberTypes.Field => ((FieldInfo)item).GetValue(obj), MemberTypes.Property => ((PropertyInfo)item).GetValue(obj), _ => throw new NotImplementedException(), }; if (value is null || string.IsNullOrEmpty(value.ToString())) { continue; } if (Exists(key)) { _values[key] = value; } else { _values.Add(key, value); } } } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public object GetValue(string key) { _values.TryGetValue(key, out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public string GetStringValue(string key) { return GetValue(key)?.ToString(); } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public double GetDoubleValue(string key) { double.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public int GetIntValue(string key) { int.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public DateTime GetDateTimeValue(string key) { DateTime.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public float GetFloatValue(string key) { float.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public decimal GetDecimalValue(string key) { decimal.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public byte GetByteValue(string key) { byte.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public char GetCharValue(string key) { char.TryParse(GetStringValue(key), out var value); return value; } /// /// 根据参数名获取参数值 /// /// 参数名 /// 参数值 public bool GetBoolValue(string key) { bool.TryParse(GetStringValue(key), out var value); return value; } /// /// 是否存在指定参数名 /// /// 参数名 /// public bool Exists(string key) => _values.ContainsKey(key); /// /// 将网关数据转成Xml格式数据 /// /// public string ToXml() { if (_values.Count == 0) { return string.Empty; } var sb = new StringBuilder(); sb.Append(""); foreach (var item in _values) { if (item.Value is string) { sb.AppendFormat("<{0}>", item.Key, item.Value); } else { sb.AppendFormat("<{0}>{1}", item.Key, item.Value); } } sb.Append(""); return sb.ToString(); } /// /// 将Xml格式数据转换为网关数据 /// /// Xml数据 /// public void FromXml(string xml) { try { Clear(); if (!string.IsNullOrEmpty(xml)) { var xmlDoc = new XmlDocument() { XmlResolver = null }; xmlDoc.LoadXml(xml); var xmlElement = xmlDoc.DocumentElement; var nodes = xmlElement.ChildNodes; foreach (var item in nodes) { var xe = (XmlElement)item; Add(xe.Name, xe.InnerText); } } } finally { Raw = xml; } } /// /// 将网关数据转换为Url格式数据 /// /// 是否需要url编码 /// public string ToUrl(bool isUrlEncode = true) { return string.Join("&", _values .Select(a => $"{a.Key}={(isUrlEncode ? WebUtility.UrlEncode(a.Value.ToString()) : a.Value.ToString())}")); } /// /// 将Url格式数据转换为网关数据 /// /// url数据 /// 是否需要url解码 /// public void FromUrl(string url, bool isUrlDecode = true) { try { Clear(); if (!string.IsNullOrEmpty(url)) { var index = url.IndexOf('?'); if (index == 0) { url = url.Substring(index + 1); } var regex = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.Compiled); var mc = regex.Matches(url); foreach (Match item in mc) { var value = item.Result("$3"); Add(item.Result("$2"), isUrlDecode ? WebUtility.UrlDecode(value) : value); } } } finally { Raw = url; } } #if NETCOREAPP3_1 /// /// 将表单数据转换为网关数据 /// /// 表单 /// public void FromForm(IFormCollection form) { try { Clear(); var allKeys = form.Keys; foreach (var item in allKeys) { Add(item, form[item]); } } catch { } } #endif /// /// 将键值对转换为网关数据 /// /// 键值对 /// public void FromNameValueCollection(NameValueCollection nvc) { foreach (var item in nvc.AllKeys) { Add(item, nvc[item]); } } /// /// 将网关数据转换为表单数据 /// /// 请求地址 /// public string ToForm(string url) { var html = new StringBuilder(); html.AppendLine(""); html.AppendLine($"
"); foreach (var item in _values) { html.AppendLine($""); } html.AppendLine("
"); html.AppendLine(""); html.AppendLine(""); return html.ToString(); } /// /// 将网关数据转成Json格式数据 /// /// public string ToJson() { return JsonConvert.SerializeObject(_values); } /// /// 将Json格式数据转成网关数据 /// /// json数据 /// public void FromJson(string json) { try { Clear(); if (!string.IsNullOrEmpty(json)) { var jObject = JObject.Parse(json); foreach (var item in jObject) { if (item.Value.Type == JTokenType.Object) { Add(item.Key, item.Value.ToString(Newtonsoft.Json.Formatting.None)); } else { Add(item.Key, item.Value.ToString()); } } } } finally { Raw = json; } } /// /// 将网关参数转为类型 /// /// 类型 /// 字符串策略 /// public T ToObject(StringCase stringCase) { var type = typeof(T); var obj = Activator.CreateInstance(type); var properties = type.GetProperties(); foreach (var item in properties) { var renameAttribute = item.GetCustomAttributes(typeof(ReNameAttribute), true); string key; if (renameAttribute.Length > 0) { key = ((ReNameAttribute)renameAttribute[0]).Name; } else { key = stringCase switch { StringCase.Snake => item.Name.ToSnakeCase(), StringCase.Camel => item.Name.ToCamelCase(), StringCase.Lower => item.Name.ToLower(), _ => item.Name }; } var value = GetStringValue(key); if (value == null) { continue; } var propertyType = item.PropertyType; if (propertyType.IsEnum) { item.SetValue(obj, Enum.Parse(propertyType, value)); } else if (propertyType.IsGenericType) { propertyType = propertyType.GenericTypeArguments[0]; if (propertyType.IsEnum) { item.SetValue(obj, Enum.Parse(propertyType, value)); } } else { item.SetValue(obj, Convert.ChangeType(value, propertyType)); } } return (T)obj; } /// /// 异步将网关参数转为类型 /// /// 类型 /// 字符串策略 /// public async Task ToObjectAsync(StringCase stringCase) { return await Task.Run(() => ToObject(stringCase)); } /// /// 清空网关数据 /// public void Clear() { _values.Clear(); } /// /// 移除指定参数 /// /// 参数名 /// public bool Remove(string key) { return _values.Remove(key); } #endregion } }