using Autofac; using Autofac.Extensions.DependencyInjection; using CoreCms.Net.Configuration; using CoreCms.Net.Loging; using Essensoft.Paylink.Alipay; using Essensoft.Paylink.WeChatPay; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using NLog.Web; using System; using System.Linq; using System.Threading.RateLimiting; using CoreCms.Net.Auth; using CoreCms.Net.Core.AutoFac; using CoreCms.Net.Core.Config; using CoreCms.Net.Filter; using CoreCms.Net.Mapping; using CoreCms.Net.Middlewares; using CoreCms.Net.Model.ViewModels.Options; using CoreCms.Net.Swagger; using CoreCms.Net.Utility; using CoreCms.Net.Web.Admin.Infrastructure; using Microsoft.Extensions.DependencyInjection.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Yitter.IdGenerator; using LogLevel = NLog.LogLevel; using Microsoft.AspNetCore.RateLimiting; using Microsoft.Extensions.Configuration; var builder = WebApplication.CreateBuilder(args); //添加本地路径获取支持 builder.Services.AddSingleton(new AppSettingsHelper(builder.Environment.ContentRootPath)); builder.Services.AddSingleton(new LogLockHelper(builder.Environment.ContentRootPath)); //Memory缓存 builder.Services.AddMemoryCacheSetup(); //Redis缓存 builder.Services.AddRedisCacheSetup(); //添加数据库连接SqlSugar注入支持 builder.Services.AddSqlSugarSetup(); //配置跨域(CORS) builder.Services.AddCorsSetup(); //添加session支持(session依赖于cache进行存储) builder.Services.AddSession(); // AutoMapper支持 builder.Services.AddAutoMapper(typeof(AutoMapperConfiguration)); // 引入Payment 依赖注入(支付宝支付/微信支付) builder.Services.AddAlipay(); builder.Services.AddWeChatPay(); //注册自定义微信接口配置文件 builder.Services.Configure(builder.Configuration.GetSection(nameof(CoreCms.Net.WeChat.Service.Options.WeChatOptions))); // 注入工厂 HTTP 客户端 builder.Services.AddHttpClient(); builder.Services.AddSingleton(); //Swagger接口文档注入 builder.Services.AddAdminSwaggerSetup(); //jwt授权支持注入 builder.Services.AddAuthorizationSetupForAdmin(); //上下文注入 builder.Services.AddHttpContextSetup(); //服务配置中加入AutoFac控制器替换规则。 builder.Services.Replace(ServiceDescriptor.Transient()); //注册mvc,注册razor引擎视图 builder.Services.AddMvc(options => { //实体验证 options.Filters.Add(); //异常处理 options.Filters.Add(); //Swagger剔除不需要加入api展示的列表 options.Conventions.Add(new ApiExplorerIgnores()); options.EnableEndpointRouting = false; }) .AddNewtonsoftJson(p => { //数据格式首字母小写 不使用驼峰 p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //不使用驼峰样式的key //p.SerializerSettings.ContractResolver = new DefaultContractResolver(); //忽略循环引用 p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //设置时间格式 p.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; }); //调用 AddRateLimiter 来将速率限制服务添加到服务集合 builder.Services.Configure(builder.Configuration.GetSection(MyRateLimitOptions.MyRateLimit)); var myOptions = new MyRateLimitOptions(); builder.Configuration.GetSection(MyRateLimitOptions.MyRateLimit).Bind(myOptions); var fixedPolicy = "fixed"; builder.Services.AddRateLimiter(_ => _ .AddFixedWindowLimiter(policyName: fixedPolicy, options => { options.PermitLimit = myOptions.PermitLimit; //options.Window = TimeSpan.FromSeconds(myOptions.Window); //不走窗口限制了。直接走请求数限制。 options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; options.QueueLimit = myOptions.QueueLimit; })); // 雪花漂移算法 // 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId: var options = new IdGeneratorOptions(1); // WorkerIdBitLength 默认值6,支持的 WorkerId 最大值为2^6-1,若 WorkerId 超过64,可设置更大的 WorkerIdBitLength // options.WorkerIdBitLength = 10; // ...... 其它参数设置参考 IdGeneratorOptions 定义,一般来说,只要再设置 WorkerIdBitLength (决定 WorkerId 的最大值)。 // 保存参数(必须的操作,否则以上设置都不能生效): YitIdHelper.SetIdGenerator(options); // 初始化以后,即可在任何需要生成ID的地方,调用以下方法: //var newId = YitIdHelper.NextId(); #region AutoFac注册============================================================================ builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer(containerBuilder => { containerBuilder.RegisterModule(new AutofacModuleRegister()); //获取所有控制器类型并使用属性注入 var controllerBaseType = typeof(ControllerBase); containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly) .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) .PropertiesAutowired(); }); #endregion #region Nlog注册============================================================================ // NLog: Setup NLog for Dependency injection builder.Logging.ClearProviders();//移除已经注册的其他日志处理程序 builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //设置最小的日志级别 builder.Host.UseNLog(); #endregion var app = builder.Build(); #region 解决Ubuntu Nginx 代理不能获取IP问题=================================================================== app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); #endregion #region 中间件注册=================================================================== // 获取用户访问真实ip app.RealIpMiddleware(); // 启用速率限制中间件 app.UseRateLimiter(); // 记录请求与返回数据 (注意开启权限,不然本地无法写入) app.UseRequestResponseLog(); // 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)(注意开启权限,不然本地无法写入) app.UseRecordAccessLogsMildd(GlobalEnumVars.CoreShopSystemCategory.Admin.ToString()); // 记录ip请求 (注意开启权限,不然本地无法写入) app.UseIpLogMildd(); #endregion app.UseSwagger().UseSwaggerUI(c => { //根据版本名称倒序 遍历展示 typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach( version => { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}"); }); c.RoutePrefix = "doc"; }); //使用 Session app.UseSession(); if (app.Environment.IsDevelopment()) { // 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。 app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } // CORS跨域 app.UseCors(AppSettingsConstVars.CorsPolicyName); // 跳转https //app.UseHttpsRedirection(); // 使用cookie app.UseCookiePolicy(); // 返回错误码 app.UseStatusCodePages(); // Routing app.UseRouting(); // 先开启认证 app.UseAuthentication(); // 然后是授权中间件 app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); //设置默认起始页(如default.html) //此处的路径是相对于wwwroot文件夹的相对路径 var defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add("index.html"); app.UseDefaultFiles(defaultFilesOptions); // 使用静态文件 app.UseStaticFiles(); try { //确保NLog.config中连接字符串与appsettings.json中同步 NLogUtil.EnsureNlogConfig("NLog.config"); //其他项目启动时需要做的事情 NLogUtil.WriteAll(LogLevel.Trace, LogType.ApiRequest, "后端启动", "后端启动成功"); app.Run(); } catch (Exception ex) { //使用Nlog写到本地日志文件(万一数据库没创建/连接成功) NLogUtil.WriteFileLog(LogLevel.Error, LogType.ApiRequest, "后端启动", "初始化数据异常", ex); throw; }