protected void Application_Start() { RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); RouteTable.Routes.IgnoreRoute("Areas/"); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); GlobalConfiguration.Configure(WebApiConfig.Register); RouteConfig.RegisterRoutes(RouteTable.Routes); //RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes); AreaRegistrationOrder.RegisterAllAreasOrder(); BundleConfig.RegisterBundles(BundleTable.Bundles); RegistAtStart.RegistStrategies(); ObjectContainer.ApplicationStart(new AutoFacContainer()); RegistAtStart.RegistPlugins(); //OnHimallStartMethodAttribute.Start(); MemberApplication.InitMessageQueue(); //delete-pengjiangxiong //App_Code.Common.LimitOrderHelper.InitLimitOrder(); //autoFac(); // ViewEngines.Engines.Insert(0, new TemplateVisualizationViewEngine()); ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(new CustomValidatorFactory())); DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; }
// 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> senparcSetting, IOptions <SenparcWeixinSetting> senparcWeixinSetting) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); app.UseHttpsRedirection(); app.ConfigureRequestPipeline(); app.StartEngine(); //static files var fileProvider = EngineContext.Current.Resolve <INopFileProvider>(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"private")), RequestPath = new PathString("/private"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"app")), RequestPath = new PathString("/app"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"AppHome")), RequestPath = new PathString("/AppHome"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"AppletHome")), RequestPath = new PathString("/AppletHome"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Areas")), RequestPath = new PathString("/Areas"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Content")), RequestPath = new PathString("/Content"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"fonts")), RequestPath = new PathString("/fonts"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"images")), RequestPath = new PathString("/images"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Printer")), RequestPath = new PathString("/Printer"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Scripts")), RequestPath = new PathString("/Scripts"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Special")), RequestPath = new PathString("/Special"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"Storage")), RequestPath = new PathString("/Storage"), OnPrepareResponse = staticFileResponse }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(fileProvider.MapPath(@"temp")), RequestPath = new PathString("/temp"), OnPrepareResponse = staticFileResponse }); //Mall Mall.Application.Configuration.InitConfiguration(); RegistAtStart.RegistStrategies(); ObjectContainer.ApplicationStart(new AutoFacContainer()); RegistAtStart.RegistPlugins(); //OnHimallStartMethodAttribute.Start(); MemberApplication.InitMessageQueue(); // 启动 CO2NET 全局注册,必须! // 关于 UseSenparcGlobal() 的更多用法见 CO2NET Demo:https://github.com/Senparc/Senparc.CO2NET/blob/master/Sample/Senparc.CO2NET.Sample.netcore3/Startup.cs var registerService = app.UseSenparcGlobal(env, senparcSetting.Value, globalRegister => { #region CO2NET 全局配置 #region 全局缓存配置(按需) //当同一个分布式缓存同时服务于多个网站(应用程序池)时,可以使用命名空间将其隔离(非必须) // globalRegister.ChangeDefaultCacheNamespace("DefaultCO2NETCache"); #region 配置和使用 Redis -- DPBMARK Redis //配置全局使用Redis缓存(按需,独立) // if (UseRedis(senparcSetting.Value, out string redisConfigurationStr))//这里为了方便不同环境的开发者进行配置,做成了判断的方式,实际开发环境一般是确定的,这里的if条件可以忽略 { /* 说明: * 1、Redis 的连接字符串信息会从 Config.SenparcSetting.Cache_Redis_Configuration 自动获取并注册,如不需要修改,下方方法可以忽略 * /* 2、如需手动修改,可以通过下方 SetConfigurationOption 方法手动设置 Redis 链接信息(仅修改配置,不立即启用) */ // Senparc.CO2NET.Cache.CsRedis.Register.SetConfigurationOption(redisConfigurationStr); //以下会立即将全局缓存设置为 Redis // Senparc.CO2NET.Cache.CsRedis.Register.UseKeyValueRedisNow();//键值对缓存策略(推荐) //Senparc.CO2NET.Cache.CsRedis.Register.UseHashRedisNow();//HashSet储存格式的缓存策略 //也可以通过以下方式自定义当前需要启用的缓存策略 //CacheStrategyFactory.RegisterObjectCacheStrategy(() => RedisObjectCacheStrategy.Instance);//键值对 //CacheStrategyFactory.RegisterObjectCacheStrategy(() => RedisHashSetObjectCacheStrategy.Instance);//HashSet #region 注册 StackExchange.Redis /* 如果需要使用 StackExchange.Redis,则可以使用 Senparc.CO2NET.Cache.Redis 库 * 注意:这一步注册和上述 CsRedis 库两选一即可,本 Sample 需要同时演示两个库,因此才都进行注册 */ //Senparc.CO2NET.Cache.Redis.Register.SetConfigurationOption(redisConfigurationStr); //Senparc.CO2NET.Cache.Redis.Register.UseKeyValueRedisNow();//键值对缓存策略(推荐) #endregion } //如果这里不进行Redis缓存启用,则目前还是默认使用内存缓存 #endregion // DPBMARK_END #region 配置和使用 Memcached -- DPBMARK Memcached //配置Memcached缓存(按需,独立) // if (UseMemcached(senparcSetting.Value, out string memcachedConfigurationStr)) //这里为了方便不同环境的开发者进行配置,做成了判断的方式,实际开发环境一般是确定的,这里的if条件可以忽略 { // app.UseEnyimMemcached(); /* 说明: * 1、Memcached 的连接字符串信息会从 Config.SenparcSetting.Cache_Memcached_Configuration 自动获取并注册,如不需要修改,下方方法可以忽略 * /* 2、如需手动修改,可以通过下方 SetConfigurationOption 方法手动设置 Memcached 链接信息(仅修改配置,不立即启用) */ // Senparc.CO2NET.Cache.Memcached.Register.SetConfigurationOption(memcachedConfigurationStr); //以下会立即将全局缓存设置为 Memcached // Senparc.CO2NET.Cache.Memcached.Register.UseMemcachedNow(); //也可以通过以下方式自定义当前需要启用的缓存策略 // CacheStrategyFactory.RegisterObjectCacheStrategy(() => MemcachedObjectCacheStrategy.Instance); } #endregion // DPBMARK_END #endregion #region 注册日志(按需,建议) globalRegister.RegisterTraceLog(ConfigTraceLog);//配置TraceLog #endregion #region APM 系统运行状态统计记录配置 //测试APM缓存过期时间(默认情况下可以不用设置) // Senparc.CO2NET.APM.Config.EnableAPM = true;//默认已经为开启,如果需要关闭,则设置为 false // Senparc.CO2NET.APM.Config.DataExpire = TimeSpan.FromMinutes(60); #endregion #endregion }, true) //使用 Senparc.Weixin SDK .UseSenparcWeixin(senparcWeixinSetting.Value, weixinRegister => { #region 微信相关配置 /* 微信配置开始 * * 建议按照以下顺序进行注册,尤其须将缓存放在第一位! */ #region 微信缓存(按需,必须放在配置开头,以确保其他可能依赖到缓存的注册过程使用正确的配置) //注意:如果使用非本地缓存,而不执行本块注册代码,将会收到“当前扩展缓存策略没有进行注册”的异常 //微信的 Redis 缓存,如果不使用则注释掉(开启前必须保证配置有效,否则会抛错) -- DPBMARK Redis /* * if (UseRedis(senparcSetting.Value, out _)) * { * weixinRegister.UseSenparcWeixinCacheCsRedis();//CsRedis,两选一 * weixinRegister.UseSenparcWeixinCacheRedis();//StackExchange.Redis,两选一 * } // DPBMARK_END * * // 微信的 Memcached 缓存,如果不使用则注释掉(开启前必须保证配置有效,否则会抛错) -- DPBMARK Memcached * if (UseMemcached(senparcSetting.Value, out _)) * { * app.UseEnyimMemcached(); * weixinRegister.UseSenparcWeixinCacheMemcached(); * } // DPBMARK_END */ #endregion #region 注册公众号或小程序(按需) weixinRegister //注册公众号(可注册多个) -- DPBMARK MP .RegisterMpAccount(senparcWeixinSetting.Value, "【盛派网络小助手】公众号") // DPBMARK_END //注册多个公众号或小程序(可注册多个) -- DPBMARK MiniProgram .RegisterWxOpenAccount(senparcWeixinSetting.Value, "【盛派网络小助手】小程序") // DPBMARK_END //除此以外,仍然可以在程序任意地方注册公众号或小程序: //AccessTokenContainer.Register(appId, appSecret, name);//命名空间:Senparc.Weixin.MP.Containers #endregion #region 注册企业号(按需) -- DPBMARK Work //注册企业微信(可注册多个) .RegisterWorkAccount(senparcWeixinSetting.Value, "【盛派网络】企业微信") //除此以外,仍然可以在程序任意地方注册企业微信: //AccessTokenContainer.Register(corpId, corpSecret, name);//命名空间:Senparc.Weixin.Work.Containers #endregion // DPBMARK_END #region 注册微信支付(按需) -- DPBMARK TenPay //注册旧微信支付版本(V2)(可注册多个) .RegisterTenpayOld(senparcWeixinSetting.Value, "【盛派网络小助手】公众号") //这里的 name 和第一个 RegisterMpAccount() 中的一致,会被记录到同一个 SenparcWeixinSettingItem 对象中 //注册最新微信支付版本(V3)(可注册多个) .RegisterTenpayV3(senparcWeixinSetting.Value, "【盛派网络小助手】公众号") //记录到同一个 SenparcWeixinSettingItem 对象中 /* 特别注意: * 在 services.AddSenparcWeixinServices() 代码中,已经自动为当前的 * senparcWeixinSetting 对应的TenpayV3 配置进行了 Cert 证书配置, * 如果此处注册的微信支付信息和默认 senparcWeixinSetting 信息不同, * 请在 ConfigureServices() 方法中使用 services.AddCertHttpClient() * 添加对应证书。 */ #endregion // DPBMARK_END #region 注册微信第三方平台(按需) -- DPBMARK Open //注册第三方平台(可注册多个) .RegisterOpenComponent(senparcWeixinSetting.Value, //getComponentVerifyTicketFunc async componentAppId => { var dir = Path.Combine(ServerUtility.ContentRootMapPath("~/App_Data/OpenTicket")); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var file = Path.Combine(dir, string.Format("{0}.txt", componentAppId)); using (var fs = new FileStream(file, FileMode.Open)) { using (var sr = new StreamReader(fs)) { var ticket = await sr.ReadToEndAsync(); sr.Close(); return(ticket); } } }, //getAuthorizerRefreshTokenFunc async(componentAppId, auhtorizerId) => { var dir = Path.Combine(ServerUtility.ContentRootMapPath("~/App_Data/AuthorizerInfo/" + componentAppId)); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var file = Path.Combine(dir, string.Format("{0}.bin", auhtorizerId)); if (!File.Exists(file)) { return(null); } using (Stream fs = new FileStream(file, FileMode.Open)) { var binFormat = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); var result = (RefreshAuthorizerTokenResult)binFormat.Deserialize(fs); fs.Close(); return(result.authorizer_refresh_token); } }, //authorizerTokenRefreshedFunc (componentAppId, auhtorizerId, refreshResult) => { var dir = Path.Combine(ServerUtility.ContentRootMapPath("~/App_Data/AuthorizerInfo/" + componentAppId)); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var file = Path.Combine(dir, string.Format("{0}.bin", auhtorizerId)); using (Stream fs = new FileStream(file, FileMode.Create)) { //这里存了整个对象,实际上只存RefreshToken也可以,有了RefreshToken就能刷新到最新的AccessToken var binFormat = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); binFormat.Serialize(fs, refreshResult); fs.Flush(); fs.Close(); } }, "【盛派网络】开放平台") //除此以外,仍然可以在程序任意地方注册开放平台: //ComponentContainer.Register();//命名空间:Senparc.Weixin.Open.Containers #endregion // DPBMARK_END ; /* 微信配置结束 */ #endregion }); #region 使用 MessageHadler 中间件,用于取代创建独立的 Controller /* * //MessageHandler 中间件介绍:https://www.cnblogs.com/szw/p/Wechat-MessageHandler-Middleware.html * * //使用公众号的 MessageHandler 中间件(不再需要创建 Controller) --DPBMARK MP * app.UseMessageHandlerForMp("/WeixinAsync", CustomMessageHandler.GenerateMessageHandler, options => * { * //说明:此代码块中演示了较为全面的功能点,简化的使用可以参考下面小程序和企业微信 * #region 配置 SenparcWeixinSetting 参数,以自动提供 Token、EncodingAESKey 等参数 * * //此处为委托,可以根据条件动态判断输入条件(必须) * options.AccountSettingFunc = context => * //方法一:使用默认配置 * senparcWeixinSetting.Value; * * //方法二:使用指定配置: * //Config.SenparcWeixinSetting["<Your SenparcWeixinSetting's name filled with Token, AppId and EncodingAESKey>"]; * * //方法三:结合 context 参数动态判断返回Setting值 * #endregion * * //对 MessageHandler 内异步方法未提供重写时,调用同步方法(按需) * options.DefaultMessageHandlerAsyncEvent = DefaultMessageHandlerAsyncEvent.SelfSynicMethod; * * //对发生异常进行处理(可选) * options.AggregateExceptionCatch = ex => * { * //逻辑处理... * return false;//系统层面抛出异常 * }; * }); // DPBMARK_END * * //使用 小程序 MessageHandler 中间件 // -- DPBMARK MiniProgram * app.UseMessageHandlerForWxOpen("/WxOpenAsync", CustomWxOpenMessageHandler.GenerateMessageHandler, options => * { * options.DefaultMessageHandlerAsyncEvent = DefaultMessageHandlerAsyncEvent.SelfSynicMethod; * options.AccountSettingFunc = context => senparcWeixinSetting.Value; * } * ); // DPBMARK_END * * //使用 企业微信 MessageHandler 中间件 // -- DPBMARK Work * app.UseMessageHandlerForWork("/WorkAsync", WorkCustomMessageHandler.GenerateMessageHandler, * o => o.AccountSettingFunc = c => senparcWeixinSetting.Value);//最简化的方式 * // DPBMARK_END */ #endregion }