## 基础配置 基础配置可以看下这个,里面整合几乎这个模板所有的配置。 ![image-20240902231627836](./images/image-20240902231627836.png) ### 数据库配置 ![image-20240902231720819](./images/image-20240902231720819.png) ### 中间件配置 ![image-20240902231705133](./images/image-20240902231705133.png) ## 后台服务设置 ### Quartz写法 - 持久化存储生成数据SQL语句参考 - https://github.com/quartznet/quartznet/tree/main/database/tables ### 原生写法 - 设置每秒执行多少,设置后台服务,原生写法 ```csharp using Microsoft.Extensions.Hosting; namespace Bunny.Service.BackgroundModule; /// /// 定时任务 /// public class TemplateBackgroundModule : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { Console.WriteLine("TemplateService started"); await Task.Delay(1000, stoppingToken); await Task.Run(() => { Console.WriteLine("执行了。。。"); }, stoppingToken); await Task.Delay(1000, stoppingToken); Console.WriteLine("--------------------------------"); } } } ``` ## 验证码生成 - 验证码生成相关配置 ```csharp var service = builder.Services; // 使用图形验证码 service.AddDistributedMemoryCache(); // 验证码相关配置内容 service.AddCaptcha(options => { options.CaptchaType = CaptchaType.DEFAULT; // 验证码类型 options.CodeLength = 4; // 验证码长度 options.ExpirySeconds = 60; // 过期时间(单位/秒) options.IgnoreCase = true; // 比较忽略大小写 options.ImageOption.Animation = true; // 是否启用动画 options.ImageOption.Width = 130; // 验证码宽度 options.ImageOption.Height = 48; // 验证码高度 options.ImageOption.BackgroundColor = SKColors.White; options.ImageOption.BubbleCount = 6; // 气泡数量 options.ImageOption.BubbleMinRadius = 2; // 气泡最小半径 options.ImageOption.BubbleMaxRadius = 6; // 气泡最大半径 options.ImageOption.BubbleThickness = 2; // 气泡边沿厚度 options.ImageOption.InterferenceLineCount = 2; // 干扰线数量 options.ImageOption.FontSize = 36; // 字体大小 options.ImageOption.FontFamily = DefaultFontFamilys.Instance.Kaiti; // 字体,中文使用kaiti,其他字符可根据喜好设置 }); } ``` ## AutoFac配置 ### 自动注入按照名称注入 **AutoFac配置详情** ```csharp using Autofac; using Bunny.Common.Attribute; using Microsoft.AspNetCore.Mvc; namespace Bunny.WebApi.Config; public static class AddAutofacConfig { /// /// AutoFac自动注入约定名称 /// 接口以Service结尾注入到IOC中 /// /// public static void BuildContainer(ContainerBuilder builder) { // 扫描所以前缀Bunny的命名空间 var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(t => t.FullName!.StartsWith("Bunny")); // 遍历注入服务 foreach (var assembly in assemblies) { var types = assembly.GetTypes(); // 注入Service var serviceTypes = types.Where(t => t.GetCustomAttributes(typeof(ServiceAttribute), false).Length != 0); foreach (var serviceType in serviceTypes) { var interfaces = serviceType.GetInterfaces(); builder.RegisterType(serviceType).As(interfaces).InstancePerDependency(); } // 注入数据库相关 var mapperTypes = types.Where(t => t.GetCustomAttributes(typeof(MapperAttribute), false).Length != 0); foreach (var mapperType in mapperTypes) { var interfaces = mapperType.GetInterfaces(); builder.RegisterType(mapperType).As(interfaces).InstancePerDependency(); } // 注入后台服务 var componentTypes = types.Where(t => t.GetCustomAttributes(typeof(ComponentAttribute), false).Length != 0); foreach (var componentType in componentTypes) builder.RegisterType(componentType).AsSelf().As().SingleInstance(); } // 如果不在在 Controller 层写构造函数可以打开这个,自动完成注入 var controllerBaseType = typeof(ControllerBase); builder.RegisterAssemblyTypes(typeof(Program).Assembly) .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) .PropertiesAutowired(); //支持属性注入 } } ``` **主程序入口配置** ```csharp // 让控制器实例由容器创建 builder.Services.Replace(ServiceDescriptor.Transient()); // 如果将Service放在 WebApi同级目录下,可以完成Controller自动注入,不需要写构造函数 builder.Services.Replace(ServiceDescriptor.Transient()); builder.Services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter())); ``` ## 日志配置 ### 数据库生成 在这里面有数据库生成内容 ![image-20240902230702816](./images/image-20240902230702816.png) 如果需要写入数据库放开这个注释 ![image-20240902230759404](./images/image-20240902230759404.png) > **配置参考** > > ```xml > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> > value="Data Source=192.168.3.98;Initial Catalog=LogManager;Persist Security Info=True;User ID=sa;Password=abc1234."/> > value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @Message, @exception)"/> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ``` ## 统一日期返回格式 对于控制器来说,需要指定返回日期格式可以看下这个, ```csharp /// /// 自定义Json转换器,用于将DateTime类型转换为JSON格式 /// public class JsonDateTimeConverter : JsonConverter { /// /// 重写读取方法,将JSON数据转换为DateTime类型 /// /// JSON读取器 /// 要转换的目标类型 /// JSON序列化选项 /// 转换后的DateTime对象 public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return DateTime.TryParse(reader.GetString(), out var date) ? date : default; } /// /// 重写写入方法,将DateTime对象转换为JSON格式并写入JSON写入器 /// /// JSON写入器 /// 要写入的DateTime对象 /// JSON序列化选项 public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { // 将DateTime对象转换为特定格式的字符串并写入JSON写入器 writer.WriteStringValue(value.ToString(LocalDateTimeConstant.DefaultDateTimeSecondFormat)); } } ``` ## 常见过滤器 Authorization Filter(授权过滤器):用于控制用户是否有权限访问特定的资源。 Action Filter(动作过滤器):在执行动作方法前后执行特定的逻辑。 Result Filter(结果过滤器):在执行结果前后执行特定的逻辑。 Exception Filter(异常过滤器):用于处理应用程序中发生的异常。 1. AuthorizationFilterAttribute 是所有过滤器中最先执行的。 用于执行授权检查。 只有一个方法:OnAuthorization,它在ActionFilterAttribute的OnActionExecuting之前执行。 如果授权失败,可以抛出AuthorizationException或返回Challenge或Forbid结果来阻止请求继续执行。 2. ResourceFilterAttribute 用于在动作方法执行前后立即执行逻辑,但比ActionFilterAttribute更早或更晚。 有两个方法:OnResourceExecuting和OnResourceExecuted。 可以用来执行需要在动作方法执行前或后立即进行的操作,例如缓存。 3. ExceptionFilterAttribute 专门用于处理异常。 有两个方法:OnException和OnExceptionAsync。 通常用于捕获和处理动作方法执行过程中抛出的异常。 由于它在异常发生后才执行,因此不适合用于清理资源,因为那时资源可能已经被破坏。 4. ResultFilterAttribute 用于在动作结果执行前后执行逻辑。 有两个方法:OnResultExecuting和OnResultExecuted。 与ActionFilterAttribute类似,但专注于动作结果的处理,例如渲染视图或返回JSON数据。 5. FormatFilterAttribute 是一个内置的过滤器,用于处理内容协商。 自动添加到控制器或动作方法上,当请求指定媒体类型时触发。 6. ServiceFilterAttribute 用于从服务容器中解析并执行一个过滤器实例。 不是直接实现过滤器逻辑,而是引用一个已经注册到依赖注入容器中的过滤器实例。 7. TypeFilterAttribute 类似于ServiceFilterAttribute,但它是通过反射创建过滤器实例,不需要过滤器在DI容器中注册。 可以接受参数,用于构造过滤器实例。