zoukankan      html  css  js  c++  java
  • 第五节:集成全局返回值处理、详解Ypf.Utils帮助类层、核心功能测试

    一. 集成全局返回值处理

     参考:

      https://www.cnblogs.com/yaopengfei/p/12362554.html 

    1. 背景

     在Core Mvc 3.x版本中,通过return Json的模式返回给前端, DateTime类型不友好(当然可以在后台强转,或者在前端转换),而且会将参数默认成首字母小写, 不是我们想要的,我们需要的是DateTime指定格式,参数名传什么显示什么。

    2. 解决方案

       我们这里采用基于Core自带的【System.Text.Json】程序集实现,需要额外引入其他程序集。

    (1). 在YpfCore.AdminWeb层中Models文件夹下,新增DatetimeJsonConverter类,用于处理需要转换的时间类型。

    代码如下:

        /// <summary>
        /// 全局日期格式转换类
        /// 基于【System.Text.Json】程序集
        /// </summary>
        public class DatetimeJsonConverter : JsonConverter<DateTime>
        {
            public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                if (reader.TokenType == JsonTokenType.String)
                {
                    if (DateTime.TryParse(reader.GetString(), out DateTime date))
                        return date;
                }
                return reader.GetDateTime();
            }
            public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
            {
                writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
            }
        }

    (2). 在ConfigureService中进行注册。

    代码分享:

     services.AddControllersWithViews()
                //全局返回格式处理
                .AddJsonOptions(options =>
                {
                    //格式化日期时间格式
                    options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
                    //参数格式首字母小写(=null 则表示参数原样输出)
                    //options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;  
                    options.JsonSerializerOptions.PropertyNamingPolicy = null;
                    //取消Unicode编码
                    options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
                    //忽略空值
                    options.JsonSerializerOptions.IgnoreNullValues = true;
                    //允许额外符号
                    options.JsonSerializerOptions.AllowTrailingCommas = true;
                    //反序列化过程中属性名称是否使用不区分大小写的比较
                    options.JsonSerializerOptions.PropertyNameCaseInsensitive = false;
                });

    二. 详解Ypf.Utils帮助类层

    截图如下:

    1. Attributes

     a.SkipAllAttribute:跨过系统所有校验。

     b.SkipLoginAttribute:跨过登录验证。

     c.SkipJwtAttribute:跨过JWT验证的特性。

    代码分享:

        /// <summary>
        /// 跨过系统所有校验
        /// </summary>
        public class SkipAllAttribute : Attribute
        {
        }
         /// <summary>
        /// 跨过JWT校验
        /// </summary>
        public class SkipJwtAttribute : Attribute
        {
        }
        /// <summary>
        /// 跨过登录校验
        /// </summary>
        public class SkipLoginAttribute : Attribute
        {
        }
    View Code

    2. Common

     a. ConfigHelp: 读取配置文件类,不依赖Core MVC的注入,支持.json和xml文件的读取。

     b. MailHelp: 邮件发送帮助类。

     c. RequestHelp: Get和Post请求,Post请求支持表单和JOSN两种格式,不依赖Core MVC注入。

     d. SftpHelp: SFTP请求相关的类

    代码分享:

    configHelp

     /// <summary>
        /// 读取配置文件
        /// 依赖程序集:【 Microsoft.Extensions.Configuration】、【Microsoft.Extensions.Configuration.FileExtensions】
        /// 【Microsoft.Extensions.Configuration.Json】、【 Microsoft.Extensions.Configuration.xml】
        /// </summary>
        public static class ConfigHelp
        {
            /// <summary>
            /// 读取Json类型的配置文件
            /// </summary>
            /// <param name="key">键名</param>
            /// <param name="FilePath">文件路径,默认为:appsettings.json</param>
            /// <returns></returns>
            public static string GetString(string key, string FilePath = "appsettings.json")
            {
                var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(FilePath, optional: true, reloadOnChange: true);
                var configuration = configurationBuilder.Build();
                return configuration[key];
            }
    
    
            /// <summary>
            /// 读取Xml类型的配置文件
            /// </summary>
            /// <param name="key">键名</param>
            /// <param name="FilePath">文件路径,默认为:myXml.json</param>
            /// <returns></returns>
            public static string GetXmlString(string key, string FilePath = "myXml.json")
            {
                var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddXmlFile(FilePath, optional: true, reloadOnChange: true);
                var configuration = configurationBuilder.Build();
                return configuration[key];
            }
    
        }
    View Code

    MailHelp

    public class MailHelp
        {
    
            #region 01-发送邮件
            /// <summary>
            /// 发送邮件
            /// </summary>
            /// <param name="subject">主题</param>
            /// <param name="content">内容</param>
            /// <param name="receiveAddress">收件人邮箱</param>
            /// <param name="attachFileList">附件路径列表</param>
            /// <param name="senderName">发件人姓名</param>
            /// <returns></returns>
            public static string SendEmail(string subject, string content, string receiveAddress, List<string> attachFileList = null,string senderName = "" )
            {
                string fromto = "1111@qq.com"; //发件人邮箱地址
    
                string name = "brucelee@qq.com"; //发件人用户名
                string upass = "lxxxx";   //发件人密码
                string smtp = "smtp.juttec.com";      //发件SMTP服务器(如果用qq邮箱发,则是:smtp.qq.com)
    
                SmtpClient _smtpClient = new SmtpClient();
                _smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;//指定电子邮件发送方式
                _smtpClient.Host = smtp; //指定SMTP服务器
                _smtpClient.Credentials = new System.Net.NetworkCredential(name, upass);//用户名和密码
    
                MailMessage _mailMessage = new MailMessage();  //表示可以使用SmtpClient发送电子邮件
                //发件人,发件人名 
                _mailMessage.From = new MailAddress(fromto, senderName);
                //收件人 
                _mailMessage.To.Add(receiveAddress);
                _mailMessage.SubjectEncoding = Encoding.UTF8;     //Encoding.GetEncoding("gb2312"); //主题内容编码
                _mailMessage.Subject = subject;//主题
                _mailMessage.Body = content;//内容
    
                //设置附件
                if (attachFileList != null && attachFileList.Count > 0)
                {
                    foreach (var item in attachFileList)
                    {
                        _mailMessage.Attachments.Add(new Attachment(item));
                    }
                }
    
                _mailMessage.BodyEncoding = Encoding.UTF8;     //Encoding.GetEncoding("gb2312");//正文编码
                _mailMessage.IsBodyHtml = true;//设置为HTML格式
                _mailMessage.Priority = MailPriority.Normal;//MailPriority.High;//优先级   
                try
                {
                    _smtpClient.Send(_mailMessage);  //将指定的邮件发送到 SMTP 服务器以便传递。
                    return "ok";
                }
                catch (Exception )
                {
                    return "error";
                }
            }
            #endregion
    
    
            #region 复杂发送(暂时注释)
            //private readonly static string SmtpServer = "smtp.wedn.net";
            //private readonly static int SmtpServerPort = 25;
            //private readonly static bool SmtpEnableSsl = false;
            //private readonly static string SmtpUsername = "server@wedn.net";
            //private readonly static string SmtpDisplayName = "Wedn.Net";
            //private readonly static string SmtpPassword = "2014@itcast";
    
            ///// <summary>
            ///// 发送邮件到指定收件人
            ///// </summary>
            ///// <param name="to">收件人地址</param>
            ///// <param name="subject">主题</param>
            ///// <param name="mailBody">正文内容(支持HTML)</param>
            ///// <param name="copyTos">抄送地址列表</param>
            ///// <returns>是否发送成功</returns>
            //public static bool Send(string to, string subject, string mailBody, params string[] copyTos)
            //{
            //    return Send(new[] { to }, subject, mailBody, copyTos, new string[] { }, MailPriority.Normal);
            //}
    
            ///// <summary>
            ///// 发送邮件到指定收件人
            ///// </summary>
            ///// <remarks>
            /////  2013-11-18 18:55 Created By iceStone
            ///// </remarks>
            ///// <param name="tos">收件人地址列表</param>
            ///// <param name="subject">主题</param>
            ///// <param name="mailBody">正文内容(支持HTML)</param>
            ///// <param name="ccs">抄送地址列表</param>
            ///// <param name="bccs">密件抄送地址列表</param>
            ///// <param name="priority">此邮件的优先级</param>
            ///// <param name="attachments">附件列表</param>
            ///// <returns>是否发送成功</returns>
            ///// <exception cref="System.ArgumentNullException">attachments</exception>
            //public static bool Send(string[] tos, string subject, string mailBody, string[] ccs, string[] bccs, MailPriority priority, params Attachment[] attachments)
            //{
            //    if (attachments == null) throw new ArgumentNullException("attachments");
            //    if (tos.Length == 0) return false;
            //    //创建Email实体
            //    var message = new MailMessage();
            //    message.From = new MailAddress(SmtpUsername, SmtpDisplayName);
            //    message.Subject = subject;
            //    message.Body = mailBody;
            //    message.BodyEncoding = Encoding.UTF8;
            //    message.IsBodyHtml = true;
            //    message.Priority = priority;
            //    //插入附件
            //    foreach (var attachment in attachments)
            //    {
            //        message.Attachments.Add(attachment);
            //    }
            //    //插入收件人地址,抄送地址和密件抄送地址
            //    foreach (var to in tos.Where(c => !string.IsNullOrEmpty(c)))
            //    {
            //        message.To.Add(new MailAddress(to));
            //    }
            //    foreach (var cc in ccs.Where(c => !string.IsNullOrEmpty(c)))
            //    {
            //        message.CC.Add(new MailAddress(cc));
            //    }
            //    foreach (var bcc in bccs.Where(c => !string.IsNullOrEmpty(c)))
            //    {
            //        message.CC.Add(new MailAddress(bcc));
            //    }
            //    //创建SMTP客户端
            //    var client = new SmtpClient
            //    {
            //        Host = SmtpServer,
            //        Credentials = new System.Net.NetworkCredential(SmtpUsername, SmtpPassword),
            //        DeliveryMethod = SmtpDeliveryMethod.Network,
            //        EnableSsl = SmtpEnableSsl,
            //        Port = SmtpServerPort
            //    };
            //    //client.SendCompleted += Client_SendCompleted;
            //    //try
            //    //{
            //    //发送邮件
            //    client.Send(message);
            //    //client.SendAsync(message,DateTime.Now.ToString());
    
            //    //client.Dispose();
            //    //message.Dispose();
            //    return true;
            //    //}
            //    //catch (Exception)
            //    //{
            //    //    throw;
            //    //}
            //} 
            #endregion
    
        }
    View Code

    RequestHelp

     /// <summary>
        /// 基于HttpClientFactory的请求封装
        /// 依赖【Microsoft.Extensions.DependencyInjection】和 【Microsoft.Extensions.Http】
        /// 可以直接调用,在CoreMvc中不再需要注入AddHttpClient了,因为下面封装里已Add进去了
        /// </summary>
        public class RequestHelp
        {
            /// <summary>
            /// Get请求
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <returns></returns>
            public static string MyGetRequest(string url)
            {
                var serviceProvider = new ServiceCollection().AddHttpClient().BuildServiceProvider();
                IHttpClientFactory clientFactory = serviceProvider.GetService<IHttpClientFactory>();
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                var client = clientFactory.CreateClient();
                var response = client.SendAsync(request).Result;
                var myResult = response.Content.ReadAsStringAsync().Result;
                return myResult;
            }
    
            /// <summary>
            /// Post请求-表单形式
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <param name="content">请求内容</param>
            /// <returns></returns>
            public static string MyPostRequest(string url, string content)
            {
                var serviceProvider = new ServiceCollection().AddHttpClient().BuildServiceProvider();
                IHttpClientFactory clientFactory = serviceProvider.GetService<IHttpClientFactory>();
                var request = new HttpRequestMessage(HttpMethod.Post, url);
                //内容的处理
                request.Content = new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded");
                var client = clientFactory.CreateClient();
                var response = client.SendAsync(request).Result;
                var myResult = response.Content.ReadAsStringAsync().Result;
                return myResult;
            }
    
            /// <summary>
            /// Post请求-Json形式
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <param name="content">请求内容</param>
            /// <returns></returns>
            public static string MyPostRequestJson(string url, object content)
            {
                var serviceProvider = new ServiceCollection().AddHttpClient().BuildServiceProvider();
                IHttpClientFactory clientFactory = serviceProvider.GetService<IHttpClientFactory>();
                var request = new HttpRequestMessage(HttpMethod.Post, url);
                //内容的处理
                request.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
                var client = clientFactory.CreateClient();
                var response = client.SendAsync(request).Result;
                var myResult = response.Content.ReadAsStringAsync().Result;
                return myResult;
            }
    
        }
    View Code

    SftpHelp

     /// <summary>
        /// SFTP相关的帮助类
        /// 依赖程序集:【SSH.NET】
        /// </summary>
        public class SftpHelp
        {
            #region 字段或属性
            private SftpClient sftp;
            /// <summary>
            /// SFTP连接状态
            /// </summary>
            public bool Connected { get { return sftp.IsConnected; } }
            #endregion
    
            #region 构造
            /// <summary>
            /// 构造
            /// </summary>
            /// <param name="host">host</param>
            /// <param name="user">用户名</param>
            /// <param name="pwd">密码</param>
            public SftpHelp(string host, string user, string pwd)
            {
                sftp = new SftpClient(host, user, pwd);
            }
            #endregion
    
            #region 连接SFTP
            /// <summary>
            /// 连接SFTP
            /// </summary>
            /// <returns>true成功</returns>
            public bool Connect()
            {
                if (!Connected)
                {
                    sftp.Connect();
                }
                return true;
            }
            #endregion
    
            #region 断开SFTP
            /// <summary>
            /// 断开SFTP
            /// </summary> 
            public void Disconnect()
            {
                try
                {
                    if (sftp != null && Connected)
                    {
                        sftp.Disconnect();
                    }
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    //throw new Exception(string.Format("断开SFTP失败,原因:{0}", ex.Message));
                }
            }
            #endregion
    
            #region SFTP上传文件
            /// <summary>
            /// SFTP上传文件
            /// </summary>
            /// <param name="localPath">本地路径</param>
            /// <param name="remotePath">远程路径</param>
            public void Put(string localPath, string remotePath)
            {
                try
                {
                    using (var file = File.OpenRead(localPath))
                    {
                        Connect();
                        sftp.UploadFile(file, remotePath);
                        Disconnect();
                    }
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    //throw new Exception(string.Format("SFTP文件上传失败,原因:{0}", ex.Message));
                }
            }
            #endregion
    
            #region SFTP获取文件
            /// <summary>
            /// SFTP获取文件
            /// </summary>
            /// <param name="remotePath">远程路径</param>
            /// <param name="localPath">本地路径</param>
            /// <returns></returns>
            public bool Get(string remotePath, string localPath)
            {
                try
                {
                    Connect();
                    var byt = sftp.ReadAllBytes(remotePath);
                    Disconnect();
                    File.WriteAllBytes(localPath, byt);
                    return true;
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    //throw new Exception(string.Format("SFTP文件获取失败,原因:{0}", ex.Message));
    
                    return false;
                }
    
            }
            #endregion
    
            #region 删除SFTP文件
            /// <summary>
            /// 删除SFTP文件 
            /// </summary>
            /// <param name="remoteFile">远程路径</param>
            public bool Delete(string remoteFile)
            {
                var isDelete = false;
                try
                {
                    Connect();
                    sftp.Delete(remoteFile);
                    isDelete = true;
                    Disconnect();
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    //throw new Exception(string.Format("SFTP文件删除失败,原因:{0}", ex.Message));
                }
                return isDelete;
            }
            #endregion
    
            #region 获取SFTP文件列表
            /// <summary>
            /// 获取SFTP文件列表
            /// </summary>
            /// <param name="remotePath">远程目录</param>
            /// <param name="fileSuffix">文件后缀</param>
            /// <returns></returns>
            public ArrayList GetFileList(string remotePath, string fileSuffix)
            {
                var objList = new ArrayList();
                try
                {
                    Connect();
                    var files = sftp.ListDirectory(remotePath);
                    Disconnect();
                    foreach (var file in files)
                    {
                        string name = file.Name;
                        if (name.Length > (fileSuffix.Length + 1) && fileSuffix == name.Substring(name.Length - fileSuffix.Length))
                        {
                            objList.Add(name);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    //throw new Exception(string.Format("SFTP文件列表获取失败,原因:{0}", ex.Message));
                }
                return objList;
            }
            #endregion
    
            #region 移动SFTP文件
            /// <summary>
            /// 移动SFTP文件
            /// </summary>
            /// <param name="oldRemotePath">旧远程路径</param>
            /// <param name="newRemotePath">新远程路径</param>
            public void Move(string oldRemotePath, string newRemotePath)
            {
                try
                {
                    Connect();
                    sftp.RenameFile(oldRemotePath, newRemotePath);
                    Disconnect();
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    //throw new Exception(string.Format("SFTP文件移动失败,原因:{0}", ex.Message));
                }
            }
            #endregion
        }
    View Code

    3. Extensions

     a. CacheStrategyExtensions: 定义缓存策略扩展方法,用于选择内存缓存、Redis缓存(提供两种程序集)、或者什么不用。

     b. CoreMvcExtensions: 提供Cookie和Session的注册、日志的注册、HttpClient的注册的扩展方法。

     c. SERedisHelp:基于程序集StackExchange.Redis的帮助类

     d. SessionExtensions: 两种组件的Session扩展方式。

     e. SortExtension:根据字段名称进行升序和降序排列的扩展,支持单字段和多字段。

    代码分享:

    CacheStrategyExtensions

    /// <summary>
        /// 缓存策略扩展
        /// </summary>
        public static class CacheStrategyExtensions
        {
            /// <summary>
            /// 添加缓存类型
            /// (最后无论哪种模式,都把AddMemoryCache注入,方便单独使用IMemoryCache)(视情况而定)
            /// </summary>
            /// <param name="services"></param>
            /// <param name="CacheType">有4种取值 (Redis:代表基于CSRedisCore使用redis缓存, 并实例化redis相关对象. Memory:代表使用内存缓存; 
            /// StackRedis: 代表基于StackExchange.Redis初始化; "null":表示什也不注入)</param>
            /// <returns></returns>
            public static IServiceCollection AddCacheStrategy(this IServiceCollection services, string CacheType)
            {
                switch (CacheType)
                {
                    case "Memory":
                        {
                            services.AddDistributedMemoryCache();
                        }; break;
                    case "Redis":
                        {
                            //基于CSRedisCore初始化
                            //初始化redis的两种使用方式
                            var csredis = new CSRedisClient(ConfigHelp.GetString("RedisStr"));
                            services.AddSingleton(csredis);
                            RedisHelper.Initialization(csredis);
    
                            //初始化缓存基于redis
                            services.AddSingleton<IDistributedCache>(new CSRedisCache(csredis));
                        }; break;
                    case "StackRedis":
                        {
                            //基于StackExchange.Redis初始化(该程序集这里不初始化缓存)
                            var connectionString = ConfigHelp.GetString("RedisStr");
                            services.AddSingleton(new SERedisHelp(connectionString));
                        }; break;
                    case "null":
                        {
                            //什么也不注入
                        }; break;
                    default: throw new Exception("缓存类型无效");
                }
                //最后都把AddMemoryCache注入,方便单独使用IMemoryCache进行内存缓存(视情况而定)
                //services.AddMemoryCache();
    
                return services;
            }
        }
    View Code

    CoreMvcExtensions:

     /// <summary>
        /// CoreMvc基础服务注册扩展
        /// </summary>
        public static class CoreMvcExtensions
        {
            /// <summary>
            /// Cookie和Session策略
            /// (基于redis的Session策略注释,如果开启,需要把CacheStrategyExtensions中的AddMemoryCache注释掉)
            /// </summary>
            /// <param name="services"></param>
            ///  <param name="CacheType">Session载体,Memory基于内存存储,StackRedis基于Redis存储,null什么也不注册</param>
            /// <returns></returns>
            public static IServiceCollection AddCookieAndSession(this IServiceCollection services, string CacheType)
            {
                //1.Cookie策略
                services.Configure<CookiePolicyOptions>(options =>
                {
                    options.CheckConsentNeeded = context => false;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
                //2. Session相关配置
                //2.1 配置Session相关的载体
                switch (CacheType)
                {
                    case "Memory":
                        {
                            services.AddDistributedMemoryCache();
                        }; break;
                    case "StackRedis":
                        {
                            //需要把其它封装中的AddMemoryCache 或 AddDistributedMemoryCache都注释掉
                            services.AddStackExchangeRedisCache(options =>
                            {
                                options.Configuration = ConfigHelp.GetString("RedisStr");
                                //options.InstanceName = "SampleInstance";   //给key加个前缀
                            });
                        }; break;
                    case "null":
                        {
                            //什么也不注册
                        }; break;
                    default: throw new Exception("Session载体无效");
                }
                //2.2 注册Session服务
                services.AddSession(options =>
                {
                    //Session的过期时间(多次访问将会被重置,默认过期时间为20分钟)
                    //另外IIS的闲置超时选项也需要配置
                    options.IdleTimeout = TimeSpan.FromMinutes(120);
                    //Cookie是必须的(默认是false),可以覆盖上面的cookie策略
                    options.Cookie.IsEssential = true;
                });
                return services;
            }
    
            /// <summary>
            /// 注册日志服务
            /// </summary>
            /// <param name="services"></param>
            /// <returns></returns>
            public static IServiceCollection AddLogStrategy(this IServiceCollection services, string logType = "SeriLog")
            { 
                if (logType == "Log4net")
                {
                    LogUtils2.InitLog();
                }
                else
                {
                    LogUtils.InitLog();
                }
                return services;
            }
    
            /// <summary>
            /// 注册HttpClient服务
            /// </summary>
            /// <param name="services"></param>
            /// <returns></returns>
            public static IServiceCollection AddMyHttpClient(this IServiceCollection services)
            {
    
                //1.基本用法
                services.AddHttpClient();
                //2. 命名客户端(用于指定表头和请求根目录---目前用不到)
                services.AddHttpClient("client1", c =>
                {
                    c.BaseAddress = new Uri("http://localhost:15319/");
                    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
                    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
                });
    
                return services;
            }
    
        }
    View Code

    SERedisHelp

     /// <summary>
        /// redis链接帮助类 
        /// 基于程序集:StackExchange.Redis
        /// </summary>
        public class SERedisHelp
        {
    
            private string _connectionString; //连接字符串
            private int _defaultDB; //默认数据库
            private readonly ConnectionMultiplexer connectionMultiplexer;
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="connectionString"></param>
            /// <param name="defaultDB">默认使用Redis的0库</param>
            public SERedisHelp(string connectionString, int defaultDB = 0)
            {
                _connectionString = connectionString;
                _defaultDB = defaultDB;
                connectionMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
            }
    
            /// <summary>
            /// 获取数据库
            /// </summary>
            /// <returns></returns>
            public IDatabase GetDatabase()
            {
                return connectionMultiplexer.GetDatabase(_defaultDB);
            }
        }
    View Code

    SessionExtensions:

    /// <summary>
        /// Session的两种扩展方式
        /// 依赖程序集:【Microsoft.AspNetCore.Http】和【Microsoft.AspNetCore.Http.Extensions】
        /// 两种序列化模式:【Newtonsoft.Json】和 【protobuf-net】
        /// 其中 【protobuf-net】序列化的类名上要加 [ProtoContract],属性上要加 [ProtoMember(1)] [ProtoMember(2)]
        /// </summary>
        public static class SessionExtensions
        {
            #region 01-利用Newtonsoft.Json进行扩展
            public static void Set<T>(this ISession session, string key, T value)
            {
                session.SetString(key, JsonConvert.SerializeObject(value));
            }
    
            public static T Get<T>(this ISession session, string key)
            {
                var value = session.GetString(key);
                return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
            }
            #endregion
    
            #region 02-利用protobuf-net进行扩展
            public static void Set2<T>(this ISession session, string key, T value)
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    Serializer.Serialize(stream, value);
                    byte[] byteArrary = stream.ToArray();
                    session.Set(key, byteArrary);
                }
            }
    
            public static T Get2<T>(this ISession session, string key)
            {
                byte[] byteArray = session.Get(key);
                if (byteArray == null)
                {
                    return default(T);
                }
                else
                {
                    using (MemoryStream stream = new MemoryStream(byteArray))
                    {
                        return Serializer.Deserialize<T>(stream);
                    }
                }
            }
            #endregion
        }
    View Code

    SortExtentsion:

     /// <summary>
        /// 排序的扩展
        /// </summary>
        public static class SortExtension
        {
    
            #region 01-根据string名称排序扩展(单字段)
            /// <summary>
            /// 根据string名称排序扩展(单字段)
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="source">排序数据源</param>
            /// <param name="sortName">排序名称</param>
            /// <param name="sortDirection">排序方式 asc或desc</param>
            /// <returns></returns>
            public static IQueryable<T> DataSorting<T>(this IQueryable<T> source, string sortName, string sortDirection)
            {
                string sortingDir = string.Empty;
                if (sortDirection.ToUpper().Trim() == "ASC")
                {
                    sortingDir = "OrderBy";
                }
                else if (sortDirection.ToUpper().Trim() == "DESC")
                {
                    sortingDir = "OrderByDescending";
                }
                ParameterExpression param = Expression.Parameter(typeof(T), sortName);
                PropertyInfo pi = typeof(T).GetProperty(sortName);
                Type[] types = new Type[2];
                types[0] = typeof(T);
                types[1] = pi.PropertyType;
                Expression expr = Expression.Call(typeof(Queryable), sortingDir, types, source.Expression, Expression.Lambda(Expression.Property(param, sortName), param));
                IQueryable<T> query = source.AsQueryable().Provider.CreateQuery<T>(expr);
                return query;
            }
            #endregion
    
            #region 02-根据多个string名称排序扩展(多字段)
            /// <summary>
            ///  根据多个string名称排序扩展(多字段)
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="data">数据源</param>
            /// <param name="orderParams">排序类</param>
            /// <returns></returns>
            public static IQueryable<T> DataManySorting<T>(this IQueryable<T> data, params FiledOrderParam[] orderParams) where T : class
            {
                var parameter = Expression.Parameter(typeof(T), "p");
                if (orderParams != null && orderParams.Length > 0)
                {
                    for (int i = 0; i < orderParams.Length; i++)
                    {
                        var property = typeof(T).GetProperty(orderParams[i].PropertyName);
                        if (property != null)
                        {
                            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
                            var orderByExpr = Expression.Lambda(propertyAccess, parameter);
                            string methodName = i > 0 ?
                                orderParams[i].IsDesc ? "ThenByDescending" : "ThenBy"
                                : orderParams[i].IsDesc ? "OrderByDescending" : "OrderBy";
                            var resultExp = Expression.Call(
                                typeof(Queryable), methodName,
                                new Type[] { typeof(T), property.PropertyType },
                                data.Expression, Expression.Quote(orderByExpr)
                                );
                            data = data.Provider.CreateQuery<T>(resultExp);
                        }
                    }
                }
                return data;
            }
    
            #endregion
        }
    
    
        /// <summary>
        /// 排序类
        /// </summary>
        public class FiledOrderParam
        {
            //是否降序
            public bool IsDesc { get; set; }
            //排序名称
            public string PropertyName { get; set; }
        }
    View Code

    4. Log

     a. Log4net: 提供配置文件和帮助类(后续将废弃)

     b. SeriLog: 提供LogUtils帮助类

    代码分享:

      详见前面的日志章节:https://www.cnblogs.com/yaopengfei/p/14244416.html

    5. Safe

     a. JWTHelp:Jwt加密和解密相关的帮助类。

     b. SecurityHelp:各种加密、解密相关算法。

    代码分享:

    JWTHelp:

    /// <summary>
        /// Jwt的加密和解密
        /// 注:加密和加密用的是用一个密钥
        /// 依赖程序集:【JWT】
        /// </summary>
        public class JWTHelp
        {
    
            /// <summary>
            /// JWT加密算法
            /// </summary>
            /// <param name="payload">负荷部分,存储使用的信息</param>
            /// <param name="secret">密钥</param>
            /// <param name="extraHeaders">存放表头额外的信息,不需要的话可以不传</param>
            /// <returns></returns>
            public static string JWTJiaM(IDictionary<string, object> payload, string secret, IDictionary<string, object> extraHeaders = null)
            {
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
                var token = encoder.Encode(payload, secret);
                return token;
            }
    
            /// <summary>
            /// JWT解密算法(新的7.x版本写法)
            /// </summary>
            /// <param name="token">需要解密的token串</param>
            /// <param name="secret">密钥</param>
            /// <returns></returns>
            public static string JWTJieM(string token, string secret)
            {
                try
                {
                    IJsonSerializer serializer = new JsonNetSerializer();
                    IDateTimeProvider provider = new UtcDateTimeProvider();
                    IJwtValidator validator = new JwtValidator(serializer, provider);
                    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                    IJwtAlgorithm algorithm = new HMACSHA256Algorithm(); // symmetric
                    IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
    
                    var json = decoder.Decode(token, secret, true);
                    //校验通过,返回解密后的字符串
                    return json;
                }
                catch (TokenExpiredException)
                {
                    //表示过期
                    return "expired";
                }
                catch (SignatureVerificationException)
                {
                    //表示验证不通过
                    return "invalid";
                }
                catch (Exception)
                {
                    return "error";
                }
            }
    
    
    
            ///// <summary>
            ///// JWT解密算法(旧的5.x版本写法)
            ///// </summary>
            ///// <param name="token">需要解密的token串</param>
            ///// <param name="secret">密钥</param>
            ///// <returns></returns>
            //public static string JWTJieM(string token, string secret)
            //{
            //    try
            //    {
            //        IJsonSerializer serializer = new JsonNetSerializer();
            //        IDateTimeProvider provider = new UtcDateTimeProvider();
            //        IJwtValidator validator = new JwtValidator(serializer, provider);
            //        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            //        IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
            //        var json = decoder.Decode(token, secret, true);
            //        //校验通过,返回解密后的字符串
            //        return json;
            //    }
            //    catch (TokenExpiredException)
            //    {
            //        //表示过期
            //        return "expired";
            //    }
            //    catch (SignatureVerificationException)
            //    {
            //        //表示验证不通过
            //        return "invalid";
            //    }
            //    catch (Exception)
            //    {
            //        return "error";
            //    }
            //}
    
    
        }
    View Code

    SecurityHelp:

     /// <summary>
        /// 各种加密解密算法
        /// 依赖程序集【NETCore.Encrypt】
        /// </summary>
        public class SecurityHelp
        {
            /// <summary>
            /// Base64编码
            /// </summary>
            /// <param name="srcString">需要编码的字符串</param>
            /// <returns></returns>
            public static string Base64Encrypt(string srcString)
            {
                return EncryptProvider.Base64Encrypt(srcString);  //default encoding is UTF-8
            }
    
            /// <summary>
            /// Base64编码
            /// </summary>
            /// <param name="encString">需要解码的字符串</param>
            /// <returns></returns>
            public static string Base64Decrypt(string encString)
            {
                return EncryptProvider.Base64Decrypt(encString);  //default encoding is UTF-8
            }
    
    
            /// <summary>
            /// MD5加密
            /// </summary>
            /// <param name="srcString">需要加密的字符串</param>
            /// <param name="num">位数,默认为32位,也可以是16位</param>
            /// <returns></returns>
            public static string Md5(string srcString, int num = 32)
            {
                if (num == 32)
                {
                    return EncryptProvider.Md5(srcString);  //默认32位
                }
                else
                {
                    return EncryptProvider.Md5(srcString, MD5Length.L16);   //16位
                }
            }
    
    
            /// <summary>
            /// SHA系列算法
            /// </summary>
            /// <param name="srcString">需要加密的字符串</param>
            /// <param name="kind">类型</param>
            /// <returns></returns>
            public static string SHA(string srcString, string kind = "Sha512")
            {
                if (kind.Equals("Sha1"))
                {
                    return EncryptProvider.Sha1(srcString);
                }
                else if (kind.Equals("Sha256"))
                {
                    return EncryptProvider.Sha256(srcString);
                }
                else if (kind.Equals("Sha384"))
                {
                    return EncryptProvider.Sha384(srcString);
                }
                else
                {
                    return EncryptProvider.Sha512(srcString);
                }
            }
    
            /// <summary>
            /// HMAC系列算法
            /// </summary>
            /// <param name="srcString">需要加密的字符串</param>
            /// <param name="secretKey">密钥</param>
            /// <param name="kind">类型</param>
            /// <returns></returns>
            public static string HMAC(string srcString, string secretKey, string kind = "HMACSHA512")
            {
                if (kind.Equals("HMACMD5"))
                {
                    return EncryptProvider.HMACMD5(srcString, secretKey);
                }
                else if (kind.Equals("HMACSHA1"))
                {
                    return EncryptProvider.HMACSHA1(srcString, secretKey);
                }
                else if (kind.Equals("HMACSHA256"))
                {
                    return EncryptProvider.HMACSHA256(srcString, secretKey);
                }
                else if (kind.Equals("HMACSHA384"))
                {
                    return EncryptProvider.HMACSHA384(srcString, secretKey);
                }
                else
                {
                    return EncryptProvider.HMACSHA512(srcString, secretKey);
                }
            }
    
    
            /// <summary>
            /// 生成AES算法所需的Key和iv
            /// (当然这里可以自己指定并保存好)
            /// </summary>
            /// <param name="key">加密所需的key</param>
            /// <param name="iv">加密所需的矢量</param>
            public static void CreateAesKey(ref string key, ref string iv)
            {
                //利用算法生成key和iv(32位和16位),当然这里可以自己指定并保存好
                var aesKey = EncryptProvider.CreateAesKey();
                key = aesKey.Key;
                iv = aesKey.IV;
            }
    
            /// <summary>
            /// AES加密算法
            /// </summary>
            /// <param name="srcString">需要加密的字符串</param>
            /// <param name="secretKey">密钥</param>
            /// <param name="iv">矢量(可以不填)</param>
            /// <returns></returns>
            public static string AESEncrypt(string srcString, string secretKey, string iv = "")
            {
                if (string.IsNullOrEmpty(iv))
                {
                    return EncryptProvider.AESEncrypt(srcString, secretKey);    //表示不需要iv矢量的AES加密算法
                }
                else
                {
                    return EncryptProvider.AESEncrypt(srcString, secretKey, iv);    //表示需要iv矢量的AES加密算法
                }
            }
    
    
            /// <summary>
            /// AES解密算法
            /// </summary>
            /// <param name="encString">需要解密的字符串</param>
            /// <param name="secretKey">密钥</param>
            /// <param name="iv">矢量(可以不填)</param>
            /// <returns></returns>
            public static string AESDecrypt(string encString, string secretKey, string iv = "")
            {
                if (string.IsNullOrEmpty(iv))
                {
                    return EncryptProvider.AESDecrypt(encString, secretKey);    //表示不需要iv矢量的AES解密算法
                }
                else
                {
                    return EncryptProvider.AESDecrypt(encString, secretKey, iv);    //表示需要iv矢量的AES解密算法
                }
            }
    
    
            /// <summary>
            /// DES加密算法
            /// </summary>
            /// <param name="srcString">需要加密的字符串</param>
            /// <param name="secretKey">密钥(这里的密钥需要是24位)</param>
            /// <returns></returns>
            public static string EDSEncrypt(string srcString, string secretKey)
            {
                return EncryptProvider.DESEncrypt(srcString, secretKey);
            }
    
    
            /// <summary>
            /// DES解密算法
            /// </summary>
            /// <param name="encString">需要解密的字符串</param>
            /// <param name="secretKey">密钥</param>
            /// <returns></returns>
            public static string DESDecrypt(string encString, string secretKey)
            {
                return EncryptProvider.DESDecrypt(encString, secretKey);
            }
    
    
    
            /// <summary>
            /// 生成RSA算法所需的Key和iv
            /// (当然这里可以自己指定并保存好)
            /// </summary>
            /// <param name="PublicKey">公钥</param>
            /// <param name="PrivateKey">私钥</param>
            public static void CreateRsaKey(ref string PublicKey, ref string PrivateKey)
            {
                //利用算法生成公钥和私钥,然后保存;当然这里可以自己指定并保存好
                var rsaKey = EncryptProvider.CreateRsaKey();    //default is 2048
                                                                // var rsaKey = EncryptProvider.CreateRsaKey(RsaSize.R3072);
                PublicKey = rsaKey.PublicKey;
                PrivateKey = rsaKey.PrivateKey;
            }
    
    
    
            /// <summary>
            /// RSA加密算法
            /// </summary>
            /// <param name="srcString">需要加密的字符串</param>
            /// <param name="publicKey">公钥 加密</param>
            /// <returns></returns>
            public static string RSAEncrypt(string srcString, string publicKey)
            {
                return EncryptProvider.RSAEncrypt(publicKey, srcString);   //公钥加密
            }
    
    
            /// <summary>
            /// RSA解密算法
            /// </summary>
            /// <param name="encString">需要解密的字符串</param>
            /// <param name="privateKey">私钥 解密</param>
            /// <returns></returns>
            public static string RSADecrypt(string encString, string privateKey)
            {
                return EncryptProvider.RSADecrypt(privateKey, encString);  //私钥解密
            }
    
    
    
        }
    
    
    
        public enum RsaSize
        {
            R2048 = 2048,
            R3072 = 3072,
            R4096 = 4096
        }
    View Code

    6. Transform

     a. JsonHelp: JSON序列化和反序列的方法,目前利用的还是NewTonSoft.Json, 基于Core3.1中 【System.Text.Json】的序列化功能不是很完善,暂时注释。

    代码分享:

     /// <summary>
        /// Json的序列化和反序列化
        /// 依赖程序集:Newtonsoft.Json; 和 Core 3.x内置的System.Text.Json
        /// System.Text.Json 不完善,有很多问题:https://www.cnblogs.com/dudu/p/11562019.html
        /// </summary>
        public class JsonHelp
        {
     
            #region 01-将JSON转换成JSON字符串
            /// <summary>
            ///将JSON转换成JSON字符串
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static string ToJsonString<T>(T obj)
            {
                return JsonConvert.SerializeObject(obj);  //Newtonsoft.Json写法
            }
            #endregion
    
            #region 02-将字符串转换成JSON对象
            /// <summary>
            /// 将字符串转换成JSON对象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="content"></param>
            /// <returns></returns>
            public static T ToObject<T>(string content)
            {
                return JsonConvert.DeserializeObject<T>(content);  //Newtonsoft.Json写法
            }
            #endregion
    
    
    
            #region 03-将JSON转换成JSON字符串(目前不成熟)
            /// <summary>
            ///将JSON转换成JSON字符串
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static string ToJsonString2<T>(T obj)
            {
                return System.Text.Json.JsonSerializer.Serialize(obj);
            }
            #endregion
    
            #region 04-将字符串转换成JSON对象(目前不成熟)
            /// <summary>
            /// 将字符串转换成JSON对象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="content"></param>
            /// <returns></returns>
            public static T ToObject2<T>(string content)
            {
                return System.Text.Json.JsonSerializer.Deserialize<T>(content);
            }
            #endregion
        }
    View Code

    三. 核心功能测试

     1. 根据字段名称进行升/降序

    代码分享:

     {
                    int pageIndex = 2;
                    int pageSize = 5;
                    //1.分开写法
                    var list1 = _baseService.Entities<T_SysUser>().Where(u => u.id != "fk").DataSorting("addTime", "desc").Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                    //2. 封装调用
                    int count = 0;
                    var list2 = _baseService.GetPageListByName<T_SysUser>(pageIndex, pageSize, out count, u => u.id != "fk", "addTime", "desc");
    
                    //3.多字段排序
                    FiledOrderParam[] param = {
                        new FiledOrderParam(){IsDesc=false,PropertyName="addTime"},
                        new FiledOrderParam(){IsDesc=true,PropertyName="id"}
                    };
                    var list3 = _baseService.Entities<T_SysUser>().Where(u => u.id != "fk").DataManySorting(param).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
    }

    对应SQL的语句:

     

     

     

     

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    cyren提供安全规则
    AC自动机——1 Trie树(字典树)介绍
    代码静态分析工具——splint的学习与使用
    Aria2+WebUI,迅雷倒下之后的代替品
    立华科技
    centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总
    Iperf使用方法与参数说明
    网络基本功(一):细说网络传输
    TCP窗口扩大选项
    TCP Nagle算法&&延迟确认机制
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/14293103.html
Copyright © 2011-2022 走看看