#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}>{0}>", item.Key, item.Value);
}
else
{
sb.AppendFormat("<{0}>{1}{0}>", 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($"");
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
}
}