/// <summary>
        /// 向应用程序添加服务并配置服务提供程序
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static IServiceProvider ConfigureApplicationServices(this IServiceCollection services, IConfigurationRoot configuration)
        {
            //获取MapleConfig配置参数并将其以单例形式注入至IServiceCollection
            //MapleConfig = 系统配置信息
            services.ConfigureStartupConfig <MapleConfig>(configuration.GetSection("Maple"));
            //获取HostingConfig配置参数并将其以单例形式注入至IServiceCollection
            //HostingConfig = 宿主机的配置信息
            services.ConfigureStartupConfig <HostingConfig>(configuration.GetSection("Hosting"));
            //注册 HttpContextAccessor 单例 ,用于DI时注入IHttpContextAccessor,以获取类似 HttpContext.Current 的效果
            services.AddHttpContextAccessor();

            //创建 Maple 引擎
            var engine = EngineContext.Create();

            //初始化 Maple 引擎  [ 指定安全协议 \ 设置应用程序根目录 \ 初始化插件 ]
            engine.Initialize(services);
            //在DI容器中注册服务 [ 查询所有实现了IMapleStartup类的实例,并确保其所在插件均已被加载 \ 按顺序执行中间件的添加和配置 \ 
            //                     注册并配置AutoMapper \ 使用 Autofac 重新注册依赖关系 \ 运行 startup 启动时的任务 ]
            var serviceProvider = engine.ConfigureServices(services, configuration);

            if (MainDataSettingsHelper.DatabaseIsInstalled())
            {
                ////如果数据库已完成配置和安装,那么开始执行计划任务
                //TaskManager.Instance.Initialize();
                //TaskManager.Instance.Start();

                //标识用于程序已启动成功
                EngineContext.Current.Resolve <ILogger <IServiceCollection> >().LogInformation("Maple Application 已启动...");
            }
            return(serviceProvider);
        }
 /// <summary>
 /// 配置处理多语言的中间件
 /// </summary>
 /// <param name="application">Builder for configuring an application's request pipeline</param>
 public static void UseCulture(this IApplicationBuilder application)
 {
     //check whether database is installed
     if (!MainDataSettingsHelper.DatabaseIsInstalled())
     {
         return;
     }
     application.UseMiddleware <CultureMiddleware>();
 }
        /// <summary>
        /// 添加身份验证中间件
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseMapleAuthentication(this IApplicationBuilder application)
        {
            //check whether database is installed
            if (!MainDataSettingsHelper.DatabaseIsInstalled())
            {
                return;
            }

            application.UseMiddleware <Services.Authentication.AuthenticationMiddleware>();
        }
        /// <summary>
        /// 添加皮肤的支持
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        public static void AddThemes(this IServiceCollection services)
        {
            if (!MainDataSettingsHelper.DatabaseIsInstalled())
            {
                return;
            }

            //themes support
            services.Configure <RazorViewEngineOptions>(options =>
            {
                options.ViewLocationExpanders.Add(new ThemeableViewLocationExpander());
            });
        }
        /// <summary>
        /// 添加异常处理设置
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public static void UseMapleExceptionHandler(this IApplicationBuilder application)
        {
            var mapleConfig              = EngineContext.Current.Resolve <MapleConfig>();
            var hostingEnvironment       = EngineContext.Current.Resolve <IHostingEnvironment>();
            var useDetailedExceptionPage = mapleConfig.DisplayFullErrorStack || hostingEnvironment.IsDevelopment();

            if (useDetailedExceptionPage)
            {
                //为开发和测试目的获得详细的异常
                application.UseDeveloperExceptionPage();
            }
            else
            {
                //为最终用户使用特殊异常处理程序
                application.UseExceptionHandler("/errorpage.htm");
            }

            //异常情况记录
            application.UseExceptionHandler(handler =>
            {
                handler.Run(context =>
                {
                    var exception = context.Features.Get <IExceptionHandlerFeature>()?.Error;
                    if (exception == null)
                    {
                        return(Task.CompletedTask);
                    }
                    try
                    {
                        //检查数据库是否已经安装配置
                        if (MainDataSettingsHelper.DatabaseIsInstalled())
                        {
                            //???
                            ////get current customer
                            //var currentCustomer = EngineContext.Current.Resolve<IWorkContext>().CurrentCustomer;
                            ////log error
                            //EngineContext.Current.Resolve<ILogger>().Error(exception.Message, exception, currentCustomer);
                        }
                    }
                    finally
                    {
                        //rethrow the exception to show the error page
                        throw exception;
                    }
                });
            });
        }
        /// <summary>
        /// Invoke middleware actions
        /// </summary>
        /// <param name="context">HTTP context</param>
        /// <param name="webHelper">Web helper</param>
        /// <returns>Task</returns>
        public async Task Invoke(Microsoft.AspNetCore.Http.HttpContext context, IWebHelper webHelper)
        {
            //判断数据库是否已安装和配置,如果没有,那么跳转至Install页面中
            if (!MainDataSettingsHelper.DatabaseIsInstalled())
            {
                var installUrl = $"{webHelper.GetTenantLocation()}install";
                if (!webHelper.GetThisPageUrl(false).StartsWith(installUrl, StringComparison.InvariantCultureIgnoreCase))
                {
                    //重定向
                    context.Response.Redirect(installUrl);
                    return;
                }
            }

            //如果已安装则进入下一个中间件
            await _next(context);
        }
Beispiel #7
0
        public async Task Invoke(HttpContext context, IWebHelper webHelper)
        {
            //TODO test. ensure that no guest record is created

            //判断数据库是否已经完成安装与配置
            if (MainDataSettingsHelper.DatabaseIsInstalled())
            {
                //未完成则继续等待
                var keepAliveUrl = $"{webHelper.GetTenantLocation()}keepalive/index";
                if (webHelper.GetThisPageUrl(false).StartsWith(keepAliveUrl, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }
            }
            //进入下一个中间件
            await _next(context);
        }
Beispiel #8
0
        public virtual IActionResult Index()
        {
            if (MainDataSettingsHelper.DatabaseIsInstalled())
            {
                return(RedirectToRoute("HomePage"));
            }

            //string host = Core.Infrastructure.EngineContext.Current
            //    .Resolve<Microsoft.AspNetCore.Http.IHttpContextAccessor>()
            //    .HttpContext?
            //    .Request?
            //    .Headers[Microsoft.Net.Http.Headers.HeaderNames.Host];

            var model = new InstallModel
            {
                AdminName = "*****@*****.**"
            };

            return(View("~/Plugins/Maple.Foundation.Setup/Views/Install/Index.cshtml", model));
        }
Beispiel #9
0
        /// <summary>
        /// 获取当前站点Host地址
        /// </summary>
        /// <param name="useSsl">是否为HTTPS</param>
        /// <returns></returns>
        public virtual string GetTenantHost(bool useSsl)
        {
            var result = string.Empty;

            //尝试从请求头中获取Host信息
            var hostHeader = _httpContextAccessor.HttpContext.Request.Headers[HeaderNames.Host];

            if (!StringValues.IsNullOrEmpty(hostHeader))
            {
                result = "http://" + hostHeader.FirstOrDefault();
            }
            else
            {
                //判断数据库是否已安装
                if (MainDataSettingsHelper.DatabaseIsInstalled())
                {
                    //获取当前站点上下文信息
                    var currentTenant = EngineContext.Current.Resolve <ITenantContext>().CurrentTenant;
                    if (currentTenant == null)
                    {
                        throw new MapleException("Current tenant cannot be loaded");
                    }
                    result = currentTenant.Url;
                }
            }

            if (!result.IsNullOrEmpty() && useSsl)
            {
                result = result.Replace("http://", "https://");
            }

            if (!result.EndsWith("/"))
            {
                result += "/";
            }

            return(result);
        }
Beispiel #10
0
        public void Configure(IApplicationBuilder application)
        {
            var mapleConfig = EngineContext.Current.Resolve <MapleConfig>();

            //启用压缩中间件
            if (mapleConfig.UseResponseCompression)
            {
                //gzip by default
                application.UseResponseCompression();

                //目前使用 DNC 2.0该问题已解决,故无需对此进行扩展了
                ////workaround with "vary" header
                //application.UseMiddleware<Compression.ResponseCompressionVaryWorkaroundMiddleware>();
            }
            //标识静态文件缓存
            application.UseStaticFiles(new StaticFileOptions
            {
                //TODO duplicated code (below)
                OnPrepareResponse = ctx =>
                {
                    if (!string.IsNullOrEmpty(mapleConfig.StaticFilesCacheControl))
                    {
                        ctx.Context.Response.Headers.Append(HeaderNames.CacheControl, mapleConfig.StaticFilesCacheControl);
                    }
                }
            });
            //默认的,静态文件存储在你的webroot目录下面,webroot的路径定义在project.json里面 "webroot": "wwwroot" ,通过UseStaticFiles() 启用
            //如果有不在webroot目录下的静态文件需要添加,那么可以通过定义FileProvider 和RequestPath 来进行设置
            //如下设置完成后,访问 http://localhost/Themes/xxxfile 则是从 当前应用程序目录中的 Themes/xxxfile 查找
            application.UseStaticFiles(new StaticFileOptions
            {
                FileProvider      = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Themes")),
                RequestPath       = new PathString("/Themes"),
                OnPrepareResponse = ctx =>
                {
                    //标识静态文件缓存
                    if (!string.IsNullOrEmpty(mapleConfig.StaticFilesCacheControl))
                    {
                        ctx.Context.Response.Headers.Append(HeaderNames.CacheControl, mapleConfig.StaticFilesCacheControl);
                    }
                }
            });
            //处理插件中的静态资源
            var staticFileOptions = new StaticFileOptions
            {
                FileProvider      = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Plugins")),
                RequestPath       = new PathString("/Plugins"),
                OnPrepareResponse = ctx =>
                {
                    //标识静态文件缓存
                    if (!string.IsNullOrEmpty(mapleConfig.StaticFilesCacheControl))
                    {
                        ctx.Context.Response.Headers.Append(HeaderNames.CacheControl, mapleConfig.StaticFilesCacheControl);
                    }
                }
            };

            if (MainDataSettingsHelper.DatabaseIsInstalled())
            {
                //此处重写,将该配置直接写入MapleConfig中
                if (!string.IsNullOrEmpty(mapleConfig.PluginStaticFileExtensionsBlacklist))
                {
                    //此类包含一个将文件扩展名映射到MIME内容类型的集合
                    //将文件后缀从列表中移除可达到设置黑名单静态文件的目的

                    var fileExtensionContentTypeProvider = new FileExtensionContentTypeProvider();
                    foreach (var ext in mapleConfig.PluginStaticFileExtensionsBlacklist
                             .Split(';', ',')
                             .Select(e => e.Trim().ToLower())
                             .Select(e => $"{(e.StartsWith(".") ? string.Empty : ".")}{e}")
                             .Where(fileExtensionContentTypeProvider.Mappings.ContainsKey))
                    {
                        fileExtensionContentTypeProvider.Mappings.Remove(ext);
                    }
                    staticFileOptions.ContentTypeProvider = fileExtensionContentTypeProvider;
                }

                //var securitySettings = EngineContext.Current.Resolve<SecuritySettings>();
                //if (!string.IsNullOrEmpty(securitySettings.PluginStaticFileExtensionsBlacklist))
                //{
                //    var fileExtensionContentTypeProvider = new FileExtensionContentTypeProvider();
                //    foreach (var ext in securitySettings.PluginStaticFileExtensionsBlacklist
                //                                        .Split(';', ',')
                //                                        .Select(e => e.Trim().ToLower())
                //                                        .Select(e => $"{(e.StartsWith(".") ? string.Empty : ".")}{e}")
                //                                        .Where(fileExtensionContentTypeProvider.Mappings.ContainsKey))
                //    {
                //        fileExtensionContentTypeProvider.Mappings.Remove(ext);
                //    }
                //    staticFileOptions.ContentTypeProvider = fileExtensionContentTypeProvider;
                //}
            }
            application.UseStaticFiles(staticFileOptions);
            //添加.bak文件下载支持
            var provider = new FileExtensionContentTypeProvider();

            provider.Mappings[".bak"] = MimeTypes.ApplicationOctetStream;
            application.UseStaticFiles(new StaticFileOptions
            {
                FileProvider        = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "db_backups")),
                RequestPath         = new PathString("/db_backups"),
                ContentTypeProvider = provider
            });
            //暂时还不知道有什么用途,检测网站是否处于运行状态?
            //check whether requested page is keep alive page
            application.UseKeepAlive();
            //启用Session
            application.UseSession();
            //启用多语言
            application.UseRequestLocalization();
        }