using Autofac; using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using System; using System.IO; using System.Text; using System.Threading.Tasks; using NPlatform.Infrastructure.Config; using NPlatform.Middleware; using NPlatform.API; using NPlatform.DI; using NPlatform.Repositories; using BZPT.IdentityServer; using Consul; using MediatR; using Newtonsoft.Json; using System.Text.Json.Serialization; using SqlSugar; using IGeekFan.AspNetCore.Knife4jUI; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using System.Security.Cryptography.X509Certificates; using BZPT.Repositories; using Microsoft.Extensions.DependencyInjection.Extensions; using NPlatform.Infrastructure.Config.Section; using ServiceStack; using LogLevel = Microsoft.Extensions.Logging.LogLevel; using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Authorization; // 创建 Web 应用构建器 var builder = WebApplication.CreateBuilder(args); var serviceConfig = builder.Configuration.GetServiceConfig(); // 配置日志 var log = builder.Logging.AddLog4Net(); log.AddConsole(); log.AddDebug(); // 添加调试日志 log.SetMinimumLevel(LogLevel.Debug); // 设置最低日志级别为 Debug // 注册服务 RegisterServices(builder); // 构建应用 var app = builder.Build(); // 配置应用中间件 ConfigureApp(app); // 运行应用 app.Run(); // 注册服务方法 void RegisterServices(WebApplicationBuilder builder) { //// 替换控制器激活器,支持属性注入 builder.Services.Replace(ServiceDescriptor.Scoped()); //builder.Services.AddSameSiteCookiePolicy(); string serviceName = serviceConfig.ServiceName; // 添加健康检查 builder.Services.AddHealthChecks().AddCheck(serviceName); // 添加内存缓存 builder.Services.AddMemoryCache(t => { t.SizeLimit = 1048576 * 500; }); // 集成 Autofac builder.Services.AddAutofac(); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); // 配置主机 builder.Host.Configure(builder.Configuration, new RepositoryOptions()); // 配置数据库上下文 ConfigureDatabaseContext(builder); // 配置控制器和 JSON 序列化 builder.Services.AddControllers(mvcOptions => { mvcOptions.Filters.Remove(mvcOptions.Filters.OfType().FirstOrDefault()); }).AddJsonOptions(options => { // 空字段不响应 options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; // 时间格式化响应 options.JsonSerializerOptions.Converters.Add(new DateTimeConverter("yyyy-MM-dd HH:mm:ss")); }); // 配置 API 行为选项 builder.Services.Configure(options => { options.InvalidModelStateResponseFactory = actionContext => { var errors = actionContext.ModelState?.Where(e => e.Value.Errors.Count > 0); StringBuilder strError = new StringBuilder(); foreach (var error in errors) { var msg = error.Value.Errors.FirstOrDefault()?.ErrorMessage; if (!string.IsNullOrWhiteSpace(msg)) strError.Append(msg); } return new FailResult("未处理异常:"+strError.ToString()); }; }); // 配置 CORS ConfigureCors(builder); // 配置 Swagger ConfigureSwagger(builder, serviceConfig); // 添加身份验证和授权服务 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { // IdentityServer 的地址 options.Authority = builder.Configuration["AuthorityServer"]; // 允许 HTTPS 不安全连接(仅用于开发环境) options.RequireHttpsMetadata = false; // API 的名称,应与 IdentityServer 中配置的 API 资源名称一致 options.ApiName =serviceConfig.ServiceID; }); // 添加授权策略 builder.Services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .Build(); }); // 全局启用授权 builder.Services.AddControllers(options => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); }); // 添加 MVC builder.Services.AddMvc(); } // 配置数据库上下文方法 void ConfigureDatabaseContext(WebApplicationBuilder builder) { var dbHost = builder.Configuration["DB_HOST"]; var dbPort = builder.Configuration["DB_PORT"]; var dbName = builder.Configuration["DB_NAME"]; var dbUser = builder.Configuration["DB_USER"]; var dbPass = builder.Configuration["DB_PASSWORD"]; builder.Services.AddSingleton(serviceProvider => { var logger = serviceProvider.GetRequiredService>(); return new DBContext($"Server={dbHost};Port={dbPort};DATABASE={dbName};User Id={dbUser};PWD={dbPass};", DbType.Dm, logger, ConfigId: "default"); }); } // 配置 Swagger 方法 void ConfigureSwagger(WebApplicationBuilder builder, IServiceConfig serviceConfig) { builder.Services.AddSwaggerGen(c => { c.SwaggerDoc($"{serviceConfig.ServiceName}", new OpenApiInfo { Title = serviceConfig.ServiceName+" 接口文档。", Version = serviceConfig.ServiceVersion }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT 授权,标头使用 Bearer 方案。示例: \"Bearer {token}\"", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey }); c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{serviceConfig.ServiceName}.xml"), true); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new List() } }); c.AddServer(new OpenApiServer() { Url = "", Description = "vvv" }); c.CustomOperationIds(apiDesc => { var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor; if (controllerAction != null) return controllerAction.ControllerName + "-" + controllerAction.ActionName; else return ""; }); }); } // 配置 CORS方法 async void ConfigureCors(WebApplicationBuilder builder) { var serviceProvider = builder.Services.BuildServiceProvider(); var dBContext = serviceProvider.GetRequiredService(); var allowedOrigins = builder.Configuration["AllowedOrigins"]; var originsArray = string.IsNullOrEmpty(allowedOrigins) ? new List() : new List(allowedOrigins.Split(',', StringSplitOptions.RemoveEmptyEntries)); builder.Services.AddCors(options => { options.AddPolicy("CorsMy", policy => { policy.AllowAnyMethod() .AllowAnyHeader() .WithOrigins(originsArray.ToArray()) // 明确指定允许的源 .AllowCredentials().SetIsOriginAllowed(_ => true); // 允许凭证(如 cookies) }); }); } // 配置应用中间件方法 void ConfigureApp(WebApplication app) { if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Fail"); app.UseHsts(); } if (!app.Environment.IsProduction()) { app.UseSwagger(); var serviceConfig = app.Configuration.GetServiceConfig(); app.UseKnife4UI(c => { c.RoutePrefix = "swagger"; c.SwaggerEndpoint($"/{serviceConfig.ServiceName}/swagger.json", serviceConfig.ServiceName); }); } app.UseHealthChecks("/healthChecks"); var defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add("index.html"); app.UseDefaultFiles(defaultFilesOptions); app.UseStaticFiles(); app.UseAntiforgery(); app.UseRouting(); app.UseCors("CorsMy"); app.UseAuthentication(); app.UseAuthorization();// 显式处理所有 OPTIONS 请求 app.MapMethods("/{**path}", new[] { "OPTIONS" }, () => Results.NoContent()) .RequireCors("CorsMy"); app.MapControllers(); app.Use(async (context, next) => { var requestPath = context.Request.Path.Value; #if DEBUG Console.WriteLine(requestPath); await next(context); return; #endif if (DateTime.Now.Hour >= 23 || DateTime.Now.Hour < 7) { context.Response.StatusCode = 400; await context.Response.WriteAsync("系统维护中~"); } else { await next(context); } }); app.MapControllers(); // 强制对控制器应用 CORS }