using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; using Senparc.CO2NET; using Senparc.CO2NET.AspNet; using Senparc.Weixin; using Senparc.Weixin.Cache.CsRedis; using Senparc.Weixin.Entities; using Senparc.Weixin.RegisterServices; using Senparc.Weixin.WxOpen; using Serilog; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; namespace YBDevice.Api { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; // 配置serilog Log.Logger = Nirvana.Common.LogFactory.GetLogger(configuration); } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSession();//使用Session(实践证明需要在配置 Mvc 之前) services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection")); //配置跨域,允许所有来源 services.AddCors(options => { options.AddPolicy("cors", builder => builder .AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod() ); }); services.AddControllersWithViews() .AddNewtonsoftJson(options => { options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //日期格式化 options.SerializerSettings.ContractResolver = new DefaultContractResolver(); })// 支持 NewtonsoftJson .SetCompatibilityVersion(CompatibilityVersion.Latest); // 注册Swagger服务 services.AddSwaggerGen(c => { // 添加文档信息 c.SwaggerDoc("v1", new OpenApiInfo { Title = "接口文档", Version = "v1", Description = "liuzl" }); // 使用反射获取xml文件。并构造出文件的路径 var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); // 启用xml注释. 该方法第二个参数启用控制器的注释,默认为false. c.IncludeXmlComments(xmlPath, true); //由于定义的实体在另一个项目中,所以这里要指定 c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "YBDevice.Entity.xml")); }); // Add CookieTempDataProvider after AddMvc and include ViewFeatures. services.AddSingleton(); //如果部署在IIS上,需要加上下面的配置: services.Configure(options => options.AllowSynchronousIO = true); #region 注入获取IP services.AddSingleton(); Nirvana.Common.MyHttpContext.serviceCollection = services; #endregion services.AddSenparcWeixinServices(Configuration);//Senparc.Weixin 注册(必须) } // 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) { //使用 Session app.UseSession(); //异常处理中间件 app.UseMyExceptionHandler(); if (env.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "YBDevice.Api v1")); } //允许body重用 app.Use(next => context => { context.Request.EnableBuffering(); return next(context); }); app.UseHttpsRedirection(); app.UseStaticFiles(); //app.UseStaticFiles(new StaticFileOptions { // FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "wwwroot")), // RequestPath = "/" //}); app.UseRouting(); //允许所有跨域,cors是在ConfigureServices方法中配置的跨域策略名称 //注意:UseCors必须放在UseRouting和UseEndpoints之间 app.UseCors("cors"); #region 微信配置 var registerService = app.UseSenparcGlobal(env, senparcSetting.Value, globalRegister => { #region CO2NET 全局配置 //配置全局使用Redis缓存(按需,独立) string redisConfigurationStr = UseRedis(senparcSetting.Value); /* 说明: * 1、Redis 的连接字符串信息会从 Config.SenparcSetting.Cache_Redis_Configuration 自动获取并注册,如不需要修改,下方方法可以忽略 /* 2、如需手动修改,可以通过下方 SetConfigurationOption 方法手动设置 Redis 链接信息(仅修改配置,不立即启用) */ Senparc.CO2NET.Cache.CsRedis.Register.SetConfigurationOption(redisConfigurationStr); //以下会立即将全局缓存设置为 Redis Senparc.CO2NET.Cache.CsRedis.Register.UseKeyValueRedisNow();//键值对缓存策略 #endregion #region 注册日志(按需,建议) globalRegister.RegisterTraceLog(ConfigTraceLog);//配置TraceLog #endregion }, true) .UseSenparcWeixin(senparcWeixinSetting.Value, weixinRegister => { #region 微信缓存(按需,必须放在配置开头,以确保其他可能依赖到缓存的注册过程使用正确的配置) //注意:如果使用非本地缓存,而不执行本块注册代码,将会收到“当前扩展缓存策略没有进行注册”的异常 //微信的 Redis 缓存,如果不使用则注释掉(开启前必须保证配置有效,否则会抛错) weixinRegister.UseSenparcWeixinCacheCsRedis();//CsRedis // weixinRegister #endregion //#region 注册公众号 //weixinRegister.RegisterMpAccount(senparcWeixinSetting.Value, "ybhdmob")// DPBMARK_END //#endregion #region 注册小程序 // .RegisterWxOpenAccount(senparcWeixinSetting.Value, "ybhdmobwxopen") #endregion // ; }); #endregion app.UseAuthorization(); app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}" ); }); } /// /// 配置微信跟踪日志(演示,按需) /// private void ConfigTraceLog() { //这里设为Debug状态时,/App_Data/WeixinTraceLog/目录下会生成日志文件记录所有的API请求日志,正式发布版本建议关闭 //如果全局的IsDebug(Senparc.CO2NET.Config.IsDebug)为false,此处可以单独设置true,否则自动为true Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog("系统日志", "系统启动");//只在Senparc.Weixin.Config.IsDebug = true的情况下生效 //全局自定义日志记录回调 Senparc.CO2NET.Trace.SenparcTrace.OnLogFunc = () => { }; //当发生基于WeixinException的异常时触发 WeixinTrace.OnWeixinExceptionFunc = ex => { //加入每次触发WeixinExceptionLog后需要执行的代码 //发送模板消息给管理员 -- DPBMARK Redis var eventService = new EventService(); eventService.ConfigOnWeixinExceptionFunc(ex); // DPBMARK_END }; } /// /// 判断当前配置是否满足使用 Redis(根据是否已经修改了默认配置字符串判断) /// /// /// private string UseRedis(SenparcSetting senparcSetting) { string redisConfigurationStr = senparcSetting.Cache_Redis_Configuration; return redisConfigurationStr; } } }