using System;
using System.Data.SqlTypes;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace utility
{
    /// <summary>
    /// Xml序列化与反序列化
    /// </summary>
    public class XmlUtil
    {
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="xml">XML字符串</param>
        /// <returns></returns>
        public static T Deserialize<T>(string xml) where T : new()
        {
            try
            {
                using (Stream sr = new FileStream(xml, FileMode.Open))
                {
                    XmlSerializer xmldes = new XmlSerializer(typeof(T));
                    return (T)xmldes.Deserialize(sr);
                }
            }
            catch
            {
                return default(T);
            }
        }
		
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static string Serializer<T>(T obj)
        {
            using (MemoryStream Stream = new MemoryStream())
            {
                XmlSerializer xml = new XmlSerializer(typeof(T));
                try
                {
                    //序列化对象
                    xml.Serialize(Stream, obj);
                }
                catch (InvalidOperationException)
                {
                    throw;
                }
                Stream.Position = 0;
                using (StreamReader sr = new StreamReader(Stream))
                {
                    return sr.ReadToEnd();
                }
            }
        }
    }
}

//源Execl名称
string sourceExeclFileName = "C:\\SourceExecl.xlsx";
//目标Execl名称
string targetExeclFileName = "C:\\TargetExecl.xlsx";
using (ExcelPackage package = new ExcelPackage(new FileInfo(targetExeclFileName)))
{
	using (ExcelPackage sourcePackage = new ExcelPackage(new FileInfo(sourceExeclFileName)))
	{
		//new sheet form copy为复制到目标Execl的SheetName
		package.Workbook.Worksheets.Add("new sheet from copy", sourcePackage.Workbook.Worksheets[1]);
	}
	package.Save();
}

/// <summary>
/// 获取日期是第几周
/// </summary>
/// <param name="date">日期</param>
/// <returns>第几周</returns>
public static int GetWeekOfYear(DateTime date)
{
	//确定此时间在一年中的位置
	int dayOfYear = date.DayOfYear;
	//当年第一天
	DateTime tempDate = new DateTime(date.Year, 1, 1);
	//确定当年第一天
	int tempDayOfWeek = (int)tempDate.DayOfWeek;
	tempDayOfWeek = tempDayOfWeek == 0 ? 7 : tempDayOfWeek;
	//确定星期几
	int index = (int)date.DayOfWeek;
	index = index == 0 ? 7 : index;
	//当前周的范围
	DateTime retStartDay = date.AddDays(-(index - 1));
	DateTime retEndDay = date.AddDays(7 - index);
	//确定当前是第几周
	int weekOfYear = (int)Math.Ceiling(((double)dayOfYear + tempDayOfWeek - 1) / 7);
	if (retStartDay.Year < retEndDay.Year)
	{
		weekOfYear = 1;
	}
	return weekOfYear;
}

默认输出的 InnerXml 显示在一行,看起来非常痛苦,特别是复杂XML文档,输出格式化后的 InnerXml 可以方便快速的查看。

public string GetFormattedInnerXml(XmlDocument doc)
{
    StringBuilder builder = new StringBuilder();
    using (StringWriter sw = new StringWriter(builder))
    {
        using (XmlTextWriter xtw = new XmlTextWriter(sw))
        {
            xtw.Formatting = Formatting.Indented;
            xtw.Indentation = 1;
            xtw.IndentChar = '\t';
            doc.WriteTo(xtw);
        }
    }
    return builder.ToString();
}

[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);

public static Guid GenerateSequentialGuid()
{
    Guid guid;
    int result = UuidCreateSequential(out guid);
    if (result != 0)
    {
        throw new ApplicationException("Create sequential guid failed: " + result);
    }
    return guid;
}

DateTime 转 Unix 时间戳

DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
int unixTimeSpan = (int)(time - startTime).TotalSeconds;

Unix 时间戳转 DateTime

DateTime dateTimeStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long longTime = long.Parse(timeStamp + "0000000");
TimeSpan toNow = new TimeSpan(longTime);
DateTime dateTime = dateTimeStart.Add(toNow);

namespace Utility.Security
{
    /// <summary>
    /// RSA加密解密
    /// </summary>
    public class RSAUtil
    {
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="str">需要加密的字符串</param>
        /// <param name="encryptKey">密钥</param>
        /// <returns>加密后的字符串</returns>
        public static string RSAEncrypt(string str, string encryptKey)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            byte[] privKeyBytes = Convert.FromBase64String(encryptKey);
            AsymmetricKeyParameter asymmetricKeyParameter = PrivateKeyFactory.CreateKey(privKeyBytes);
            IAsymmetricBlockCipher signer = new Pkcs1Encoding(new RsaEngine());
            signer.Init(true, asymmetricKeyParameter);
            //加密
            byte[] encryptBytes = signer.ProcessBlock(bytes, 0, bytes.Length);
            string rsaString = Convert.ToBase64String(encryptBytes);
            return rsaString;
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="str">需要解密的字符串</param>
        /// <param name="decryptKey">密钥</param>
        /// <returns>解密后的字符串</returns>
        public static string RSADecrypt(string str, string decryptKey)
        {
            byte[] strBytes = Convert.FromBase64String(str);
            byte[] keyBytes = Convert.FromBase64String(decryptKey);
            AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
            IAsymmetricBlockCipher signer = new Pkcs1Encoding(new RsaEngine());
            signer.Init(false, asymmetricKeyParameter);
            byte[] decryptedBytes = signer.ProcessBlock(strBytes, 0, strBytes.Length);
            string decryptString = Encoding.UTF8.GetString(decryptedBytes);
            return decryptString;
        }
    }
}

解决 Linq 的 lambda 表达式排序不够灵活问题。

namespace Utility.Linq
{
    public static class QueryableExtend
    {
        /// <summary>
        /// 根据键按升序对序列的元素排序
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "OrderBy");
            return source;
        }

        /// <summary>
        /// 根据键按降序对序列的元素排序
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> OrderByDescending<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "OrderByDescending");
            return source;
        }

        /// <summary>
        /// 根据某个键按降序对序列中的元素执行后续排序。
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <param name="isDescending">是否倒序(可选,默认否)</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> ThenBy<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "ThenBy");
            return source;
        }

        /// <summary>
        /// 使用指定的比较器按降序对序列中的元素执行后续排序。
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <param name="isDescending">是否倒序(可选,默认否)</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> ThenByDescending<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "ThenByDescending");
            return source;
        }

        /// <summary>
        /// 根据键按升序对序列的元素排序
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <param name="methodName">排序方法名</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string field, string methodName)
        {
            if(source == null)
            {
                throw new ArgumentException("source");
            }
            if(field == null)
            {
                throw new ArgumentException("field");
            }
            if(methodName == null)
            {
                throw new ArgumentException("methodName");
            }
            Type entityType = typeof(TSource);
            ParameterExpression parameterExpression = Expression.Parameter(entityType, entityType.FullName);
            Expression propertyExpression = Expression.Property(parameterExpression, entityType.GetProperty(field));
            Expression expression = Expression.Lambda(propertyExpression, parameterExpression);
            PropertyInfo propertyInfo = entityType.GetProperty(field);
            Type propertyType = propertyInfo.PropertyType;
            Expression expr = Expression.Call(typeof(Queryable), methodName, new Type[] { entityType, propertyType }, source.Expression, expression);
            source = source.Provider.CreateQuery<TSource>(expr);
            return source;
        }
    }
}

namespace Provider.Payment.Alipay
{
    public class AlipayUtil
    {
        /// <summary>
        /// 生成签名
        /// 相关文档:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.vwCvxF&treeId=62&articleId=104741&docType=1
        /// </summary>
        /// <param name="obj">要签名的对象</param>
        /// <param name="signKey">签名密匙</param>
        /// <returns>签名字符串</returns>
        public static string GenerateSign(object entity, string signKey)
        {
            SortedDictionary<string, object> sorted = GetSortedDictionary(entity);
            return GenerateSign(sorted, signKey);
        }
        /// <summary>
        /// 生成签名
        /// </summary>
        /// <remarks>
        /// 相关文档:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.vwCvxF&treeId=62&articleId=104741&docType=1
        /// </remarks>
        /// <param name="obj">要签名的对象</param>
        /// <param name="signKey">签名密匙</param>
        /// <returns>签名字符串</returns>
        public static string GenerateSign(SortedDictionary<string, object> sorted, string signKey)
        {
            StringBuilder builder = new StringBuilder();
            foreach (KeyValuePair<string, object> pair in sorted)
            {
                if (pair.Key != "sign" && pair.Key != "sign_type")
                {
                    object value = pair.Value;
                    Type type = pair.Value.GetType();
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        type = type.GetGenericArguments()[0];
                    }
                    if (type == typeof(DateTime))
                    {
                        value = Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    builder.Append(pair.Key + "=" + value + "&");
                }
            }
            string str = builder.Remove(builder.Length - 1, 1).ToString() + signKey;
            string sign = MD5Encrypt(str);
            return sign;
        }
        /// <summary>
        /// 获得属性值并排序
        /// </summary>
        /// <param name="entity">参数</param>
        /// <returns></returns>
        protected static SortedDictionary<string, object> GetSortedDictionary(object entity)
        {
            Type type = entity.GetType();
            PropertyInfo[] propertys = type.GetProperties();
            SortedDictionary<string, object> sorted = new SortedDictionary<string, object>();
            foreach (PropertyInfo property in propertys)
            {
                Type propertyType = property.GetType();
                object objValue = null;
                if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    bool HasValue = (bool)type.GetProperty("HasValue").GetValue(entity, null);
                    if (HasValue)
                    {
                        objValue = type.GetProperty("Value").GetValue(entity, null);
                    }
                }
                else
                {
                    objValue = property.GetValue(entity, null);
                }
                string value = (objValue ?? "").ToString();
                if (!String.IsNullOrEmpty(value))
                {
                    sorted.Add(property.Name, value);
                }
            }
            return sorted;
        }
        /// <summary>
        /// MD5加密
        /// </summary>
        protected static string MD5Encrypt(string input)
        {
            MD5 md5 = MD5.Create();
            byte[] bytes = Encoding.UTF8.GetBytes(input);
            byte[] buffer = md5.ComputeHash(bytes);
            StringBuilder builder = new StringBuilder();
            foreach (byte b in buffer)
            {
                builder.Append(b.ToString("x2"));
            }
            return builder.ToString();
        }
    }
}