using Autofac; using New_College.Common; using New_College.Common.LogHelper; using New_College.Extensions; using New_College.Filter; using New_College.Hubs; using New_College.IServices; using New_College.Middlewares; using New_College.Model.Seed; using New_College.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Reflection; using New_College.Model.ViewModels; using Microsoft.AspNetCore.Http; using IdentityModel; using Microsoft.AspNetCore.Authentication.Cookies; using Newtonsoft.Json.Converters; using New_College.Common.Helper; using System.Text.Encodings.Web; using System.Text.Unicode; using Microsoft.AspNetCore.ResponseCompression; using System.Linq; namespace New_College { public class Startup { private IServiceCollection _services; public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Env = env; } 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) { // 以下code可能与文章中不一样,对代码做了封装,具体查看右侧 Extensions 文件夹. services.AddSingleton(); services.AddSingleton(); services.AddSingleton(new Appsettings(Configuration)); services.AddSingleton(new LogLock(Env.ContentRootPath)); Permissions.IsUseIds4 = Appsettings.app(new string[] { "Startup", "IdentityServer4", "Enabled" }).ObjToBool(); //短信配置 AliyunSmsSenderConfig.accessKeyId = Appsettings.app(new string[] { "AliyunSmsSenderConfig", "accessKeyId" }).ObjToString(); AliyunSmsSenderConfig.accessKeySecret = Appsettings.app(new string[] { "AliyunSmsSenderConfig", "accessKeySecret" }).ObjToString(); WeixinConfig.Appid = Appsettings.app(new string[] { "Weixin", "Appid" }).ObjToString(); WeixinConfig.Secret = Appsettings.app(new string[] { "Weixin", "Secret" }).ObjToString(); WeixinConfig.MCHID = Appsettings.app(new string[] { "Weixin", "MCHID" }).ObjToString(); WeixinConfig.KEY = Appsettings.app(new string[] { "Weixin", "KEY" }).ObjToString(); WeixinConfig.NotifyUrl = Appsettings.app(new string[] { "WeChatPay", "NotifyUrl" }).ObjToString(); WeixinConfig.APIv3Key = Appsettings.app(new string[] { "WeChatPay", "APIv3Key" }).ObjToString(); WeixinConfig.SerialNumber= Appsettings.app(new string[] { "WeChatPay", "SerialNumber" }).ObjToString(); WeixinConfig.PrivateKey = Appsettings.app(new string[] { "WeChatPay", "PrivateKey" }).ObjToString(); //阿里云oss配置 AliYunOssConfig.wendpoint = Appsettings.app(new string[] { "AliYunOss", "wendpoint" }).ObjToString(); AliYunOssConfig.accessKeyId = Appsettings.app(new string[] { "AliYunOss", "accessKeyId" }).ObjToString(); AliYunOssConfig.accessKeySecret = Appsettings.app(new string[] { "AliYunOss", "accessKeySecret" }).ObjToString(); AliYunOssConfig.bucket = Appsettings.app(new string[] { "AliYunOss", "bucket" }).ObjToString(); AliYunOssConfig.endpoint = Appsettings.app(new string[] { "AliYunOss", "endpoint" }).ObjToString(); ///三方验证接口 CasdoorConfig.Endpoint = Appsettings.app(new string[] { "Casdoor", "Endpoint" }); CasdoorConfig.ClientId = Appsettings.app(new string[] { "Casdoor", "ClientId" }); CasdoorConfig.ClientSecret = Appsettings.app(new string[] { "Casdoor", "ClientSecret" }); CasdoorConfig.CallbackPath = Appsettings.app(new string[] { "Casdoor", "CallbackPath" }); services.AddMemoryCacheSetup(); services.AddSqlsugarSetup(); services.AddDbSetup(); services.AddAutoMapperSetup(); services.AddCorsSetup(); services.AddMiniProfilerSetup(); services.AddSwaggerSetup(); services.AddJobSetup(); services.AddHttpContextSetup(); services.AddAppConfigSetup(); services.AddHttpApi(); // 授权+认证 (jwt or ids4) services.AddAuthorizationSetup(); if (Permissions.IsUseIds4) { services.AddAuthentication_Ids4Setup(); } else { services.AddAuthentication_JWTSetup(); } services.AddIpPolicyRateLimitSetup(Configuration); services.AddSignalR().AddNewtonsoftJsonProtocol(); services.AddScoped(); services.Configure(x => x.AllowSynchronousIO = true) .Configure(x => x.AllowSynchronousIO = true); services.AddSession(); services.AddControllers(o => { // 全局异常过滤 o.Filters.Add(typeof(GlobalExceptionsFilter)); // 全局路由权限公约 //o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention()); // 全局路由前缀,统一修改路由 o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name))); }).AddJsonOptions( options => { //格式化日期时间格式 options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter("yyyy-MM-dd HH:mm:ss")); //数据格式首字母小写 //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; ////忽略循环引用 //options.JsonSerializerOptions.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; ////不使用驼峰样式的key //options.SerializerSettings.ContractResolver = new DefaultContractResolver(); ////设置时间格式 //options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; ////忽略Model中为null的属性 ////options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; ////设置本地时间而非UTC时间 //options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; ////添加Enum转string //options.SerializerSettings.Converters.Add(new StringEnumConverter()); ////将long类型转为string //options.SerializerSettings.Converters.Add(new NumberConverter(NumberConverterShip.Int64)); }); //全局配置Json序列化处理 services.AddMvc().AddSessionStateTempDataProvider(); services.AddResponseCompression(options => { options.Providers.Add(); options.Providers.Add(); options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "application/json" }); }); services.AddSession(); _services = services; } // 注意在Program.CreateHostBuilder,添加Autofac服务工厂 public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterModule(new AutofacModuleRegister()); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MyContext myContext, ITasksQzServices tasksQzServices, ISchedulerCenter schedulerCenter, IHostApplicationLifetime lifetime) { // Ip限流,尽量放管道外层 app.UseIpLimitMildd(); // 记录请求与返回数据 app.UseReuestResponseLog(); // signalr app.UseSignalRSendMildd(); // 记录ip请求 app.UseIPLogMildd(); // 查看注入的所有服务 app.UseAllServicesMildd(_services); app.UseResponseCompression(); if (env.IsDevelopment()) { // 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。 app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // 在非开发环境中,使用HTTP严格安全传输(or HSTS) 对于保护web安全是非常重要的。 // 强制实施 HTTPS 在 ASP.NET Core,配合 app.UseHttpsRedirection //app.UseHsts(); } app.UseSession(); app.UseSwaggerAuthorized(); // 封装Swagger展示 app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("New_College.Api.index.html")); // ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓ // CORS跨域 app.UseCors(Appsettings.app(new string[] { "Startup", "Cors", "PolicyName" })); // 跳转https //app.UseHttpsRedirection(); // 使用静态文件 app.UseStaticFiles(); // 使用cookie app.UseCookiePolicy(); app.UseSession(); // 返回错误码 app.UseStatusCodePages(); // Routing app.UseRouting(); // 这种自定义授权中间件,可以尝试,但不推荐 // app.UseJwtTokenAuth(); // 先开启认证 app.UseAuthentication(); // 然后是授权中间件 app.UseAuthorization(); // 开启异常中间件,要放到最后 //app.UseExceptionHandlerMidd(); // 性能分析 //app.UseMiniProfiler(); // 用户访问记录 app.UseRecordAccessLogsMildd(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapHub("/api2/chatHub"); }); // 生成种子数据 app.UseSeedDataMildd(myContext, Env.WebRootPath); // 开启QuartzNetJob调度服务 app.UseQuartzJobMildd(tasksQzServices, schedulerCenter); //服务注册 app.UseConsulMildd(Configuration, lifetime); } } }