| using System; | 
| using System.Collections.Generic; | 
| using System.IO; | 
| using System.Linq; | 
| using System.Reflection; | 
| using System.Text; | 
| using System.Threading.Tasks; | 
| using Autofac; | 
| using Microsoft.AspNetCore.Authentication.JwtBearer; | 
| using Microsoft.AspNetCore.Builder; | 
| using Microsoft.AspNetCore.Hosting; | 
| using Microsoft.AspNetCore.Http; | 
| using Microsoft.AspNetCore.Http.Features; | 
| using Microsoft.AspNetCore.Mvc; | 
| using Microsoft.AspNetCore.Mvc.Controllers; | 
| using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; | 
| using Microsoft.AspNetCore.Server.Kestrel.Core; | 
| using Microsoft.Extensions.Configuration; | 
| using Microsoft.Extensions.DependencyInjection; | 
| using Microsoft.Extensions.FileProviders; | 
| using Microsoft.Extensions.Hosting; | 
| using Microsoft.IdentityModel.Tokens; | 
| using Microsoft.OpenApi.Models; | 
| using Newtonsoft.Json; | 
| using Quartz; | 
| using Quartz.Impl; | 
| using Swashbuckle.AspNetCore.SwaggerGen; | 
| using WIDESEA_Core.Configuration; | 
| using WIDESEA_Core.Extensions; | 
| using WIDESEA_Core.Filters; | 
| using WIDESEA_Core.FreeDB; | 
| using WIDESEA_Core.Middleware; | 
| using WIDESEA_Core.ObjectActionValidator; | 
| using WIDESEA_Core.Utilities.PDFHelper; | 
| using WIDESEA_Core.WorkFlow; | 
| using WIDESEA_Entity.DomainModels; | 
|   | 
| namespace WIDESEA_WebApi | 
| { | 
|     public class Startup | 
|     { | 
|         public Startup(IConfiguration configuration) | 
|         { | 
|             Configuration = configuration; | 
|         } | 
|   | 
|         public IConfiguration Configuration { get; } | 
|         private IServiceCollection Services { get; set; } | 
|         // This method gets called by the runtime. Use this method to add services to the container. | 
|         public void ConfigureServices(IServiceCollection services) | 
|         { | 
|             //初始化模型验证配置 | 
|             services.UseMethodsModelParameters().UseMethodsGeneralParameters(); | 
|             services.AddSingleton<IObjectModelValidator>(new NullObjectModelValidator()); | 
|             Services = services; | 
|             // services.Replace( ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>()); | 
|             services.AddSession(); | 
|             services.AddMemoryCache(); | 
|             services.AddHttpContextAccessor(); | 
|             services.AddMvc(options => | 
|             { | 
|                 options.Filters.Add(typeof(ApiAuthorizeFilter)); | 
|                 options.Filters.Add(typeof(ActionExecuteFilter)); | 
|                 //  options.SuppressAsyncSuffixInActionNames = false; | 
|             }); | 
|             services.AddControllers() | 
|               .AddNewtonsoftJson(op => | 
|               { | 
|                   op.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); | 
|                   op.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; | 
|               }); | 
|   | 
|             Services.AddAuthentication(options => | 
|             { | 
|                 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; | 
|                 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; | 
|             }) | 
|              .AddJwtBearer(options => | 
|              { | 
|                  options.TokenValidationParameters = new TokenValidationParameters | 
|                  { | 
|                      SaveSigninToken = true,//保存token,后台验证token是否生效(重要) | 
|                      ValidateIssuer = true,//是否验证Issuer | 
|                      ValidateAudience = true,//是否验证Audience | 
|                      ValidateLifetime = true,//是否验证失效时间 | 
|                      ValidateIssuerSigningKey = true,//是否验证SecurityKey | 
|                      ValidAudience = AppSetting.Secret.Audience,//Audience | 
|                      ValidIssuer = AppSetting.Secret.Issuer,//Issuer,这两项和前面签发jwt的设置一致 | 
|                      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSetting.Secret.JWT)) | 
|                  }; | 
|                  options.Events = new JwtBearerEvents() | 
|                  { | 
|                      OnChallenge = context => | 
|                      { | 
|                          context.HandleResponse(); | 
|                          context.Response.Clear(); | 
|                          context.Response.ContentType = "application/json"; | 
|                          context.Response.StatusCode = 401; | 
|                          context.Response.WriteAsync(new { message = "授权未通过", status = false, code = 401 }.Serialize()); | 
|                          return Task.CompletedTask; | 
|                      } | 
|                  }; | 
|              }); | 
|             //必须appsettings.json中配置 | 
|             string corsUrls = Configuration["CorsUrls"]; | 
|             if (string.IsNullOrEmpty(corsUrls)) | 
|             { | 
|                 throw new Exception("请配置跨请求的前端Url"); | 
|             } | 
|             services.AddCors(options => | 
|             { | 
|                 options.AddDefaultPolicy( | 
|                         builder => | 
|                         { | 
|                             builder.AllowAnyOrigin() | 
|                            .SetPreflightMaxAge(TimeSpan.FromSeconds(2520)) | 
|                             .AllowAnyHeader().AllowAnyMethod(); | 
|                         }); | 
|             }); | 
|             services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | 
|             services.AddControllers(); | 
|             services.AddSwaggerGen(c => | 
|             { | 
|                 //分为2份接口文档 | 
|                 c.SwaggerDoc("v1", new OpenApiInfo { Title = "WIDESEA_Core后台Api", Version = "v1", Description = "这是对文档的描述。。" }); | 
|                 c.SwaggerDoc("v2", new OpenApiInfo { Title = "WIDESEA_Core对外三方Api", Version = "v2", Description = "xxx接口文档" });  //控制器里使用[ApiExplorerSettings(GroupName = "v2")]               | 
|                                                                                                                                  //启用中文注释功能 | 
|                                                                                                                                  // var basePath = PlatformServices.Default.Application.ApplicationBasePath; | 
|                                                                                                                                  //  var xmlPath = Path.Combine(basePath, "WIDESEA_WebApi.xml"); | 
|                                                                                                                                  //   c.IncludeXmlComments(xmlPath, true);//显示控制器xml注释内容 | 
|                                                                                                                                  //添加过滤器 可自定义添加对控制器的注释描述 | 
|                                                                                                                                  //c.DocumentFilter<SwaggerDocTag>(); | 
|   | 
|                 var security = new Dictionary<string, IEnumerable<string>> { { AppSetting.Secret.Issuer, new string[] { } } }; | 
|                 c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() | 
|                 { | 
|                     Description = "JWT授权token前面需要加上字段Bearer与一个空格,如Bearer token", | 
|                     Name = "Authorization", | 
|                     In = ParameterLocation.Header, | 
|                     Type = SecuritySchemeType.ApiKey, | 
|                     BearerFormat = "JWT", | 
|                     Scheme = "Bearer" | 
|                 }); | 
|                 #region 启用中文注释功能 | 
|                 //WIDESEA_WebApi下的PropertyGroup添加<GenerateDocumentationFile>true</GenerateDocumentationFile><!--启用中文注释功能--> | 
|                 //启用中文注释功能 | 
|                 var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; | 
|                 //IncludeXmlComments true 显示控制器注释 | 
|                 c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true); | 
|                 #endregion | 
|                 c.AddSecurityRequirement(new OpenApiSecurityRequirement | 
|                 { | 
|                     { | 
|                         new OpenApiSecurityScheme | 
|                         { | 
|                             Reference = new OpenApiReference { | 
|                                 Type = ReferenceType.SecurityScheme, | 
|                                 Id = "Bearer" | 
|                             } | 
|                         }, | 
|                         new string[] { } | 
|                     } | 
|                 }); | 
|             }) | 
|              .AddControllers() | 
|             .ConfigureApiBehaviorOptions(options => | 
|             { | 
|                 options.SuppressConsumesConstraintForFormFileParameters = true; | 
|                 options.SuppressInferBindingSourcesForParameters = true; | 
|                 options.SuppressModelStateInvalidFilter = true; | 
|                 options.SuppressMapClientErrors = true; | 
|                 options.ClientErrorMapping[404].Link = | 
|                     "https://*/404"; | 
|             }); | 
|             //services.AddSignalR(); | 
|             //services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools())); | 
|             //services.AddTransient<IPDFService, PDFService>(); | 
|             services.AddHttpClient(); | 
|   | 
|             //设置文件上传大小限制 | 
|             //设置文件上传大小限制 | 
|             services.Configure<FormOptions>(x => | 
|             { | 
|                 x.MultipartBodyLengthLimit = 1024 * 1024 * 100;//100M | 
|             }); | 
|             services.Configure<KestrelServerOptions>(options => | 
|             { | 
|                 options.Limits.MaxRequestBodySize = 1024 * 1024 * 100;//100M | 
|             }); | 
|             services.Configure<IISServerOptions>(options => | 
|             { | 
|                 options.MaxRequestBodySize = 1024 * 1024 * 100;//100M | 
|             }); | 
|         } | 
|   | 
|         public void ConfigureContainer(ContainerBuilder builder) | 
|         { | 
|             Services.AddModule(builder, Configuration); | 
|         } | 
|   | 
|         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | 
|         public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | 
|         { | 
|             if (env.IsDevelopment()) | 
|             { | 
|                 app.UseDeveloperExceptionPage(); | 
|             } | 
|             else | 
|             { | 
|                 //app.UseQuartz(env); | 
|             } | 
|             new FreeDB(); | 
|             app.UseMiddleware<ExceptionHandlerMiddleWare>(); | 
|             app.UseStaticFiles().UseStaticFiles(new StaticFileOptions | 
|             { | 
|                 ServeUnknownFileTypes = true | 
|             }); | 
|             app.UseDefaultFiles(); | 
|             app.Use(HttpRequestMiddleware.Context); | 
|   | 
|             //2021.06.27增加创建默认upload文件夹 | 
|             string _uploadPath = (env.ContentRootPath + "/Upload").ReplacePath(); | 
|   | 
|             if (!Directory.Exists(_uploadPath)) | 
|             { | 
|                 Directory.CreateDirectory(_uploadPath); | 
|             } | 
|   | 
|             app.UseStaticFiles(new StaticFileOptions() | 
|             { | 
|                 FileProvider = new PhysicalFileProvider( | 
|                 Path.Combine(Directory.GetCurrentDirectory(), @"Upload")), | 
|                 //配置访问虚拟目录时文件夹别名 | 
|                 RequestPath = "/Upload", | 
|                 OnPrepareResponse = (staticFile) => | 
|                 { | 
|                     //可以在此处读取请求的信息进行权限认证 | 
|                     //  staticFile.File | 
|                     //  staticFile.Context.Response.StatusCode; | 
|                 } | 
|             }); | 
|             //配置HttpContext | 
|             app.UseStaticHttpContext(); | 
|   | 
|             app.UseSwagger(); | 
|             app.UseSwaggerUI(c => | 
|             { | 
|                 //2个下拉框选项  选择对应的文档 | 
|                 c.SwaggerEndpoint("/swagger/v1/swagger.json", "WIDESEA_Core后台Api"); | 
|                 c.SwaggerEndpoint("/swagger/v2/swagger.json", "测试第三方Api"); | 
|                 c.RoutePrefix = ""; | 
|             }); | 
|             app.UseRouting(); | 
|             app.UseCors(); | 
|             app.UseAuthentication(); | 
|             app.UseAuthorization(); | 
|             app.UseEndpoints(endpoints => | 
|             { | 
|                 endpoints.MapControllers(); | 
|             }); | 
|         } | 
|     } | 
|   | 
|     /// <summary> | 
|     /// Swagger注释帮助类 | 
|     /// </summary> | 
|     public class SwaggerDocTag : IDocumentFilter | 
|     { | 
|         /// <summary> | 
|         /// 添加附加注释 | 
|         /// </summary> | 
|         /// <param name="swaggerDoc"></param> | 
|         /// <param name="context"></param> | 
|         public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) | 
|         { | 
|             //添加对应的控制器描述 | 
|             swaggerDoc.Tags = new List<OpenApiTag> | 
|             { | 
|                 new OpenApiTag { Name = "Test", Description = "这是描述" }, | 
|                 //new OpenApiTag { Name = "你的控制器名字,不带Controller", Description = "控制器描述" }, | 
|             }; | 
|         } | 
|     } | 
| } |