using Autofac; using AutoMapper; using CoreCms.Net.Auth; using CoreCms.Net.Configuration; using CoreCms.Net.Core.AutoFac; using CoreCms.Net.Core.Config; using CoreCms.Net.Filter; using CoreCms.Net.Loging; using CoreCms.Net.Mapping; using CoreCms.Net.Middlewares; using CoreCms.Net.Model.ViewModels.Options; using CoreCms.Net.Model.ViewModels.Sms; using CoreCms.Net.Services.Mediator; using CoreCms.Net.Swagger; using CoreCms.Net.Task; using Essensoft.AspNetCore.Payment.Alipay; using Essensoft.AspNetCore.Payment.WeChatPay; using Hangfire; using Hangfire.Dashboard.BasicAuthorization; using InitQ; using MediatR; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Qc.YilianyunSdk; using Senparc.CO2NET; using Senparc.CO2NET.AspNet; using Senparc.Weixin; using Senparc.Weixin.Entities; using Senparc.Weixin.RegisterServices; using Senparc.Weixin.WxOpen; using System; using System.Collections.Generic; using System.Linq; using CoreCms.Net.RedisMQ.Subscribe; using CoreCms.Net.Utility.Extensions; namespace CoreCms.Net.Web.WebApi { /// /// 启动配置 /// public class Startup { /// /// 构造函数 /// /// /// public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Env = env; } /// /// 配置属性 /// public IConfiguration Configuration { get; } /// /// web环境 /// public IWebHostEnvironment Env { get; } /// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //添加本地路径获取支持 services.AddSingleton(new AppSettingsHelper(Env.ContentRootPath)); services.AddSingleton(new LogLockHelper(Env.ContentRootPath)); //Memory缓存 services.AddMemoryCacheSetup(); //Redis缓存 services.AddRedisCacheSetup(); //添加数据库连接SqlSugar注入支持 services.AddSqlSugarSetup(); //配置跨域(CORS) services.AddCorsSetup(); //添加session支持(session依赖于cache进行存储) services.AddSession(); // AutoMapper支持 services.AddAutoMapper(typeof(AutoMapperConfiguration)); //MediatR services.AddMediatR(typeof(OrderPayedCommand).Assembly); //使用 SignalR services.AddSignalR(); //Redis消息队列 services.AddRedisMessageQueueSetup(); // 引入Payment 依赖注入(支付宝支付/微信支付) services.AddAlipay(); services.AddWeChatPay(); // 在 appsettings.json 中 配置选项 services.Configure(Configuration.GetSection("WeChatPay")); services.Configure(Configuration.GetSection("Alipay")); //Swagger接口文档注入 services.AddClientSwaggerSetup(); //配置易联云打印机 services.AddYiLianYunSetup(); //授权支持注入 services.AddAuthorizationSetupForClient(); //上下文注入 services.AddHttpContextSetup(); //微信注册 services.AddSenparcWeixinServices(Configuration); //服务配置中加入AutoFac控制器替换规则。 services.Replace(ServiceDescriptor.Transient()); //注册mvc,注册razor引擎视图 services.AddMvc(options => { //实体验证 options.Filters.Add(); //异常处理 options.Filters.Add(); //Swagger剔除不需要加入api展示的列表 options.Conventions.Add(new ApiExplorerIgnores()); }) .AddNewtonsoftJson(p => { //数据格式首字母小写 不使用驼峰 p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //不使用驼峰样式的key //p.SerializerSettings.ContractResolver = new DefaultContractResolver(); //忽略循环引用 p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //设置时间格式(必须使用yyyy/MM/dd格式,因为ios系统不支持2018-03-29格式的时间,只识别2018/03/09这种格式。) p.SerializerSettings.DateFormatString = "yyyy/MM/dd HH:mm:ss"; }); } /// /// Autofac规则配置 /// /// public void ConfigureContainer(ContainerBuilder builder) { //获取所有控制器类型并使用属性注入 var controllerBaseType = typeof(ControllerBase); builder.RegisterAssemblyTypes(typeof(Program).Assembly) .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) .PropertiesAutowired(); builder.RegisterModule(new AutofacModuleRegister()); } // public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions senparcSetting, IOptions senparcWeixinSetting) /// /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// /// /// /// /// public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions senparcSetting, IOptions senparcWeixinSetting) { // 记录请求与返回数据 (注意开启权限,不然本地无法写入) app.UseReuestResponseLog(); // 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)(注意开启权限,不然本地无法写入) app.UseRecordAccessLogsMildd(); // 记录ip请求 (注意开启权限,不然本地无法写入) app.UseIpLogMildd(); //强制显示中文 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN"); app.UseSwagger().UseSwaggerUI(c => { //根据版本名称倒序 遍历展示 typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach( version => { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}"); }); //设置默认跳转到swagger-ui c.RoutePrefix = "doc"; //c.RoutePrefix = string.Empty; }); #region Hangfire定时任务 var queues = new string[] { GlobalEnumVars.HangFireQueuesConfig.@default.ToString(), GlobalEnumVars.HangFireQueuesConfig.apis.ToString(), GlobalEnumVars.HangFireQueuesConfig.web.ToString(), GlobalEnumVars.HangFireQueuesConfig.recurring.ToString() }; app.UseHangfireServer(new BackgroundJobServerOptions { ServerTimeout = TimeSpan.FromMinutes(4), SchedulePollingInterval = TimeSpan.FromSeconds(15),//秒级任务需要配置短点,一般任务可以配置默认时间,默认15秒 ShutdownTimeout = TimeSpan.FromMinutes(30),//超时时间 Queues = queues,//队列 WorkerCount = Math.Max(Environment.ProcessorCount, 20)//工作线程数,当前允许的最大线程,默认20 }); //授权 var filter = new BasicAuthAuthorizationFilter( new BasicAuthAuthorizationFilterOptions { SslRedirect = false, // Require secure connection for dashboard RequireSsl = false, // Case sensitive login checking LoginCaseSensitive = false, // Users Users = new[] { new BasicAuthAuthorizationUser { Login = AppSettingsConstVars.HangFireLogin, PasswordClear = AppSettingsConstVars.HangFirePassWord } } }); var options = new DashboardOptions { AppPath = "/",//返回时跳转的地址 DisplayStorageConnectionString = false,//是否显示数据库连接信息 Authorization = new[] { filter }, IsReadOnlyFunc = Context => { return false;//是否只读面板 } }; app.UseHangfireDashboard("/job", options); //可以改变Dashboard的url HangfireDispose.HangfireService(); #endregion #region 盛派微信注册 // 启动 CO2NET 全局注册,必须! var registerService = app.UseSenparcGlobal(env, senparcSetting.Value, globalRegister => { #region CO2NET 全局配置 #endregion }, true) //使用 Senparc.Weixin SDK .UseSenparcWeixin(senparcWeixinSetting.Value, weixinRegister => { #region 微信相关配置 /* 微信配置开始 * * 建议按照以下顺序进行注册,尤其须将缓存放在第一位! */ #region 注册公众号或小程序(按需) weixinRegister //注册公众号 //.RegisterMpAccount(senparcWeixinSetting.Value, "公众号") //注册多个公众号或小程序 .RegisterWxOpenAccount(senparcWeixinSetting.Value, "小程序") //AccessTokenContainer.Register(appId, appSecret, name);//命名空间:Senparc.Weixin.MP.Containers #endregion ; /* 微信配置结束 */ #endregion }); #endregion //使用 Session app.UseSession(); if (env.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); // Routing app.UseRouting(); // 使用静态文件 app.UseStaticFiles(); // 先开启认证 app.UseAuthentication(); // 然后是授权中间件 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( "areas", "{area:exists}/{controller=Default}/{action=Index}/{id?}" ); //endpoints.MapControllers(); endpoints.MapControllerRoute( "default", "{controller=Default}/{action=Index}/{id?}"); }); //设置默认起始页(如default.html) //此处的路径是相对于wwwroot文件夹的相对路径 var defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add("index.html"); app.UseDefaultFiles(defaultFilesOptions); app.UseStaticFiles(); } } }