using Admin.Core.Api.PLTBusiness; using Admin.Core.Common; using Admin.Core.Extensions; using Admin.Core.IService.ISys; using Admin.Core.Plc; using Admin.Core.RunPlc; using Admin.Core.Tasks; using Autofac; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; 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.FileProviders; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; using System.IdentityModel.Tokens.Jwt; using System.IO; using System.Linq; using System.Reflection; using System.Text; using TouchSocket.Http; namespace Admin.Core.Api { /// /// Startup /// public class Startup { /// /// Startup /// /// /// public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Env = env; } /// /// IConfiguration /// public IConfiguration Configuration { get; } /// /// 环境信息:开发/生产 /// 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) { //Appsettings services.AddSingleton(new Appsettings(Configuration)); //日志文件目录 services.AddSingleton(new LogLock(Env.ContentRootPath)); //jwt或Ids4权限方案 Permissions.IsUseIds4 = Appsettings.app(new string[] { "Startup", "IdentityServer4", "Enabled" }).ObjToBool(); // 确保从认证中心返回的ClaimType不被更改,不使用Map映射 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); //Memory缓存 services.AddMemoryCacheSetup(); //Swagger services.AddSwaggerSetup(); //Sqlsugar数据库模型查询 services.AddSqlsugarSetup(); //AutoMapper services.AddAutoMapperSetup(); //跨域 services.AddCorsSetup(); //性能分析 //services.AddMiniProfilerSetup(); //HttpContext上下文 services.AddHttpContextSetup(); // 授权+认证 (jwt or ids4) services.AddAuthorizationSetup(); if (Permissions.IsUseIds4) { services.AddAuthentication_Ids4Setup(); } else { services.AddAuthentication_JWTSetup(); } //IPLimit限流 services.AddIpPolicyRateLimitSetup(Configuration); //筛选器 //services.AddScoped(); services.Configure(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. // Default is true, make it false options.CheckConsentNeeded = context => false; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDistributedMemoryCache(); services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); //注册http请求服务 services.AddHttpClient(); //任务调度 services.AddJobSetup(); //添加PLC services.AddPlcSetup(); //添加服务 //services.AddHostedService(); //services.AddScoped(); //Redis缓存 //services.AddRedisCacheSetup(); //Redis队列 //services.AddRedisInitMqSetup(); //EventBus //services.AddEventBusSetup(); //SignalR //services.AddSignalR().AddNewtonsoftJsonProtocol(); //kestrel //services.Configure(x => x.AllowSynchronousIO = true) // .Configure(x => x.AllowSynchronousIO = true); //Controller services.AddControllers(o => { // 全局异常过滤 o.Filters.Add(typeof(GlobalExceptionsFilter)); // 全局路由权限公约 //o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention()); // 全局路由前缀,统一修改路由 o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name))); }) //全局配置Json序列化处理 .AddNewtonsoftJson(options => { //忽略循环引用 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //不使用驼峰样式的key options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //忽略Model中为null的属性 options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; // 设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //设置本地时间而非UTC时间 options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; }); services.Replace(ServiceDescriptor.Transient()); //支持编码大全 例如:支持 System.Text.Encoding.GetEncoding("GB2312") System.Text.Encoding.GetEncoding("GB18030") Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); } //private X509Certificate2 GetCertificate() //{ // var assembly = typeof(Startup).GetTypeInfo().Assembly; // using (var stream = assembly.GetManifestResourceStream( // assembly.GetManifestResourceNames().First(r => r.EndsWith("cnblogs.pfx")))) // { // if (stream == null) // throw new ArgumentNullException(nameof(stream)); // var bytes = new byte[stream.Length]; // stream.Read(bytes, 0, bytes.Length); // return new X509Certificate2(bytes); // } //} /// /// 注意在Program.CreateHostBuilder,添加Autofac服务工厂 /// /// public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterModule(new AutofacModuleRegister()); builder.RegisterModule(); } /// /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// /// /// public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISysTasksQzService tasksQzService, ISchedulerCenter schedulerCenter, IRunPlcService plc) { // Ip限流,尽量放管道外层 app.UseIpLimitMildd(); // 记录请求与返回数据 app.UseReuestResponseLog(); // 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流) app.UseRecordAccessLogsMildd(); // signalr //app.UseSignalRSendMildd(); // 记录ip请求 app.UseIPLogMildd(); if (env.IsDevelopment()) { // 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。 app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // 在非开发环境中,使用HTTP严格安全传输(or HSTS) 对于保护web安全是非常重要的。 // 强制实施 HTTPS 在 ASP.NET Core,配合 app.UseHttpsRedirection //app.UseHsts(); } // 封装Swagger展示 app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Admin.Core.Api.index.html")); // ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓ // CORS跨域 app.UseCors(Appsettings.app(new string[] { "Startup", "Cors", "PolicyName" })); // 跳转https //app.UseHttpsRedirection(); // 使用静态文件,注意:如果开启需在对应目录创建文件夹,否则会报错 // app.UseStaticFiles(new StaticFileOptions // { // FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "file")), // RequestPath = "/file", // OnPrepareResponse = ctx => // { // ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600"); // } // }); // // 使用静态文件 // app.UseStaticFiles(); app.UseSession(); //app.UseCookiePolicy(); // 返回错误码 app.UseStatusCodePages(); // Routing app.UseRouting(); // 自定义授权中间件,可以尝试,但不推荐 // app.UseJwtTokenAuth(); // 先开启认证 app.UseAuthentication(); // 然后是授权中间件 app.UseAuthorization(); //开启性能分析 //app.UseMiniProfilerMildd(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); //使用集线器 //endpoints.MapHub("/chatHub"); //GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null; }); // 开启QuartzNetJob调度服务 app.UseQuartzJobMildd(tasksQzService, schedulerCenter); //PLC app.UsePlcMildd(plc); // 服务注册 //app.UseConsulMildd(Configuration, lifetime); // 事件总线,订阅服务 //app.ConfigureEventBus(); } } }