/// <summary> /// 构造函数 /// </summary> /// <param name="controllerContext"></param> /// <param name="viewPath"></param> /// <param name="layoutPath"></param> /// <param name="isPartialView"></param> /// <param name="applicationKey"></param> /// <param name="findLayoutPathOfThemeDelegate"></param> /// <param name="themeAppearance"></param> /// <param name="viewPageActivator"></param> public ThemedRazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool isPartialView, string applicationKey, Func<ThemeAppearance, string, string, string> findLayoutPathOfThemeDelegate, ThemeAppearance themeAppearance, IViewPageActivator viewPageActivator) : base(controllerContext, viewPath, viewPageActivator) { IsPartialView = isPartialView; ApplicationKey = applicationKey; if (!IsPartialView) { if (!string.IsNullOrEmpty(layoutPath)) OverridenLayoutPath = layoutPath; else { OverridenLayoutPath = string.Empty; ThemeAppearance = themeAppearance; FindLayoutPathOfThemeDelegate = findLayoutPathOfThemeDelegate; } } }
/// <summary> /// 获取应用模块中的ViewPath /// </summary> /// <remarks> /// 应用模块以外的功能View定位忽略Area /// </remarks> /// <param name="themeAppearance"></param> /// <param name="viewName"></param> /// <param name="controllerName"></param> /// <returns></returns> private string GetViewPathOfTheme(ThemeAppearance themeAppearance, string viewName, string controllerName) { StringBuilder cacheKeyBuilder = new StringBuilder("viewPath:"); cacheKeyBuilder.Append(themeAppearance.PresentAreaKey); cacheKeyBuilder.AppendFormat(",{0}", themeAppearance.ThemeKey); cacheKeyBuilder.AppendFormat(",{0}", controllerName); cacheKeyBuilder.AppendFormat(",{0}", viewName); string cacheKey = cacheKeyBuilder.ToString(); ICacheService cacheService = DIContainer.Resolve<ICacheService>(); string viewPath = cacheService.Get<string>(cacheKey); if (viewPath == null) { if (IsSpecificPath(viewName)) { viewPath = GetPathFromSpecificName(viewName); } else { //{3}:PresentAreaKey,{2}:ThemeKey,{1}:ControllerName,{0}:ViewName List<string> viewLocations = new List<string>(); viewLocations.Add(string.Format("~/Themes/{3}/{2}/Views/{1}/{0}.cshtml", viewName, controllerName, themeAppearance.ThemeKey, themeAppearance.PresentAreaKey)); //如果Theme有Parent,则把Parent的路径也作为查找路径 Theme theme = ThemeService.GetTheme(themeAppearance.PresentAreaKey, themeAppearance.ThemeKey); if (!string.IsNullOrEmpty(theme.Parent)) viewLocations.Add(string.Format("~/Themes/{3}/{2}/Views/{1}/{0}.cshtml", viewName, controllerName, theme.Parent, themeAppearance.PresentAreaKey)); //最后在~/Themes/Shared/Views/中查找 viewLocations.Add(string.Format("~/Themes/Shared/Views/{0}.cshtml", viewName)); foreach (var viewLocation in viewLocations) { if (VirtualPathProvider.FileExists(viewLocation)) { viewPath = viewLocation; break; } } } if (viewPath != null) cacheService.Add(cacheKey, viewPath, CachingExpirationType.Stable); } if (viewPath == null) { throw new ExceptionFacade(new ResourceExceptionDescriptor("The ViewName {0} Of the controllerName {0} could not be found!", viewName, controllerName)); } return viewPath; }
/// <summary> /// 获取Layout具体地址 /// </summary> /// <param name="themeAppearance"></param> /// <param name="layoutName">布局文件名称不要带.cshtml</param> /// <param name="applicationKey">应用模块标识</param> private string GetLayoutPathOfTheme(ThemeAppearance themeAppearance, string layoutName, string applicationKey) { if (string.IsNullOrEmpty(layoutName)) return String.Empty; bool isFromApplication = !string.IsNullOrEmpty(applicationKey); StringBuilder cacheKeyBuilder = new StringBuilder("layoutPath:"); cacheKeyBuilder.Append(themeAppearance.PresentAreaKey); cacheKeyBuilder.AppendFormat(",{0}", themeAppearance.ThemeKey); cacheKeyBuilder.AppendFormat(",{0}", themeAppearance.PresentAreaKey); cacheKeyBuilder.AppendFormat(",{0}", layoutName); if (isFromApplication) cacheKeyBuilder.AppendFormat(",{0}", applicationKey); string cacheKey = cacheKeyBuilder.ToString(); ICacheService cacheService = DIContainer.Resolve<ICacheService>(); string layoutPath = cacheService.Get<string>(cacheKey); if (layoutPath == null) { if (IsSpecificPath(layoutName)) { layoutPath = GetPathFromSpecificName(layoutName); } else { List<string> layoutLocations = new List<string>(); if (isFromApplication) layoutLocations.Add(string.Format("~/Applications/{1}/Layouts/{0}.cshtml", layoutName, applicationKey)); //{2}:PresentAreaKey,{1}:ThemeKey,{0}:LayoutName layoutLocations.Add(string.Format("~/Themes/{2}/{1}/Layouts/{0}.cshtml", layoutName, themeAppearance.ThemeKey, themeAppearance.PresentAreaKey)); //如果Theme有Parent,则把Parent的路径也作为查找路径 Theme theme = ThemeService.GetTheme(themeAppearance.PresentAreaKey, themeAppearance.ThemeKey); if (!string.IsNullOrEmpty(theme.Parent)) layoutLocations.Add(string.Format("~/Themes/{2}/{1}/Layouts/{0}.cshtml", layoutName, theme.Parent, themeAppearance.PresentAreaKey)); //在呈现区域的公共Layouts路径查找 layoutLocations.Add(string.Format("~/Themes/{1}/Layouts/{0}.cshtml", layoutName, themeAppearance.PresentAreaKey)); //最后在~/Themes/Shared/Views/中查找 layoutLocations.Add(string.Format("~/Themes/Shared/Views/{0}.cshtml", layoutName)); foreach (var viewLocation in layoutLocations) { if (VirtualPathProvider.FileExists(viewLocation)) { layoutPath = viewLocation; break; } } } if (layoutPath != null) cacheService.Add(cacheKey, layoutPath, CachingExpirationType.Stable); } if (layoutPath == null) { throw new ExceptionFacade(new ResourceExceptionDescriptor("The LayoutName {0} could not be found!", layoutName)); } return layoutPath; }
/// <summary> /// 提取皮肤 /// </summary> /// <param name="presentAreaKey">呈现区域</param> /// <param name="fileName">皮肤文件名</param> /// <param name="fileStream">皮肤文件流</param> public void ExtractThemeAppearance(string presentAreaKey, string fileName, Stream fileStream) { if (fileStream == null || !fileStream.CanRead) return; string tempKey = fileName.Substring(0, fileName.LastIndexOf(".")); string tempPath = WebUtility.GetPhysicalFilePath(string.Format("~/Themes/{0}/temp/{1}", presentAreaKey, tempKey)); if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath); string fileFullName = Path.Combine(tempPath, fileName); //将皮肤包存储到指定目录 SaveThemeAppearancePackage(fileFullName, fileStream); #region 解压压缩包 Ionic.Zip.ReadOptions ro = new Ionic.Zip.ReadOptions(); ro.Encoding = System.Text.Encoding.UTF8; using (Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(fileFullName, ro)) { foreach (Ionic.Zip.ZipEntry zipEntry in zip) { zipEntry.Extract(tempPath, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently); } } #endregion string[] themeConfigFileNames = Directory.GetFiles(tempPath, "Theme.config", SearchOption.AllDirectories); if (themeConfigFileNames != null && themeConfigFileNames.Length > 0) { var themeConfigFileName = themeConfigFileNames[0]; XElement themeElement = XElement.Load(themeConfigFileName); if (themeElement == null) { Directory.Delete(tempPath, true); throw new ExceptionFacade("Theme.config配置文件格式不正确"); } var parentDirectory = Directory.GetParent(themeConfigFileName); //解析外观 string appearancesPath = Path.Combine(parentDirectory.FullName, "Appearances"); int displayOrder = GetThemeAppearances(presentAreaKey, null).Max(n => n.DisplayOrder) + 1; string themeKey = string.Empty; foreach (var appearanceDirectory in Directory.GetDirectories(appearancesPath)) { string appearanceConfig = Path.Combine(appearanceDirectory, "Appearance.config"); XElement appearanceElement = XElement.Load(appearanceConfig); if (appearanceElement == null) { Directory.Delete(appearanceDirectory, true); throw new ExceptionFacade("Appearance.config配置文件格式不正确"); } string appearanceKey = appearanceDirectory.TrimEnd('\\').Substring(appearanceDirectory.LastIndexOf("\\") + 1); ThemeAppearance themeAppearance = new ThemeAppearance(appearanceElement, appearanceKey); themeAppearance.DisplayOrder = displayOrder; displayOrder++; if (appearanceRepository.Get(themeAppearance.Id) != null) appearanceRepository.Update(themeAppearance); else { appearanceRepository.Insert(themeAppearance); } if (string.IsNullOrEmpty(themeKey)) themeKey = themeAppearance.ThemeKey; } //解析主题 Theme theme = new Theme(themeElement, themeKey); if (GetTheme(theme.Id) != null) { themeRepository.Update(theme); } else themeRepository.Insert(theme); string themePath = WebUtility.GetPhysicalFilePath(string.Format("~/Themes/{0}/{1}", presentAreaKey, themeKey)); //移动目录 if (Directory.Exists(themePath)) Directory.Delete(themePath, true); parentDirectory.MoveTo(themePath); if (Directory.Exists(tempPath)) Directory.Delete(tempPath, true); } else { string[] appearanceConfigFileNames = Directory.GetFiles(tempPath, "Appearance.config", SearchOption.AllDirectories); if (appearanceConfigFileNames != null && appearanceConfigFileNames.Length > 0) { string appearanceConfigFileName = appearanceConfigFileNames[0]; XElement appearanceDocument = XElement.Load(appearanceConfigFileName); if (appearanceDocument == null) { Directory.Delete(tempPath, true); throw new ExceptionFacade("Appearance.config配置文件格式不正确"); } //获取父级目录 var parentDirectory = Directory.GetParent(appearanceConfigFileName); ThemeAppearance themeAppearance = new ThemeAppearance(appearanceDocument, parentDirectory.Name); themeAppearance.DisplayOrder = GetThemeAppearances(presentAreaKey, null).Max(n => n.DisplayOrder) + 1; string appearancesPath = WebUtility.GetPhysicalFilePath(string.Format("~/Themes/{0}/{1}/Appearances/", presentAreaKey, themeAppearance.ThemeKey)); //更新数据库 if (appearanceRepository.Get(themeAppearance.Id) != null) appearanceRepository.Update(themeAppearance); else appearanceRepository.Insert(themeAppearance); string appearancePath = Path.Combine(appearancesPath, themeAppearance.AppearanceKey); //移动目录 if (Directory.Exists(appearancePath)) Directory.Delete(appearancePath, true); parentDirectory.MoveTo(appearancePath); if (Directory.Exists(tempPath)) Directory.Delete(tempPath, true); } else { Directory.Delete(tempPath, true); throw new ExceptionFacade("找不到Appearance.config文件,您上传的不是皮肤包"); } } }
/// <summary> /// 提取皮肤 /// </summary> /// <param name="presentAreaKey">呈现区域</param> /// <param name="fileName">皮肤文件名</param> /// <param name="fileStream">皮肤文件流</param> public void ExtractThemeAppearance(string presentAreaKey, string fileName, Stream fileStream) { if (fileStream == null || !fileStream.CanRead) { return; } string tempKey = fileName.Substring(0, fileName.LastIndexOf(".")); string tempPath = WebUtility.GetPhysicalFilePath(string.Format("~/Themes/{0}/temp/{1}", presentAreaKey, tempKey)); if (!Directory.Exists(tempPath)) { Directory.CreateDirectory(tempPath); } string fileFullName = Path.Combine(tempPath, fileName); //将皮肤包存储到指定目录 SaveThemeAppearancePackage(fileFullName, fileStream); #region 解压压缩包 Ionic.Zip.ReadOptions ro = new Ionic.Zip.ReadOptions(); ro.Encoding = System.Text.Encoding.UTF8; using (Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(fileFullName, ro)) { foreach (Ionic.Zip.ZipEntry zipEntry in zip) { zipEntry.Extract(tempPath, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently); } } #endregion string[] themeConfigFileNames = Directory.GetFiles(tempPath, "Theme.config", SearchOption.AllDirectories); if (themeConfigFileNames != null && themeConfigFileNames.Length > 0) { var themeConfigFileName = themeConfigFileNames[0]; XElement themeElement = XElement.Load(themeConfigFileName); if (themeElement == null) { Directory.Delete(tempPath, true); throw new ExceptionFacade("Theme.config配置文件格式不正确"); } var parentDirectory = Directory.GetParent(themeConfigFileName); //解析外观 string appearancesPath = Path.Combine(parentDirectory.FullName, "Appearances"); int displayOrder = GetThemeAppearances(presentAreaKey, null).Max(n => n.DisplayOrder) + 1; string themeKey = string.Empty; foreach (var appearanceDirectory in Directory.GetDirectories(appearancesPath)) { string appearanceConfig = Path.Combine(appearanceDirectory, "Appearance.config"); XElement appearanceElement = XElement.Load(appearanceConfig); if (appearanceElement == null) { Directory.Delete(appearanceDirectory, true); throw new ExceptionFacade("Appearance.config配置文件格式不正确"); } string appearanceKey = appearanceDirectory.TrimEnd('\\').Substring(appearanceDirectory.LastIndexOf("\\") + 1); ThemeAppearance themeAppearance = new ThemeAppearance(appearanceElement, appearanceKey); themeAppearance.DisplayOrder = displayOrder; displayOrder++; if (appearanceRepository.Get(themeAppearance.Id) != null) { appearanceRepository.Update(themeAppearance); } else { appearanceRepository.Insert(themeAppearance); } if (string.IsNullOrEmpty(themeKey)) { themeKey = themeAppearance.ThemeKey; } } //解析主题 Theme theme = new Theme(themeElement, themeKey); if (GetTheme(theme.Id) != null) { themeRepository.Update(theme); } else { themeRepository.Insert(theme); } string themePath = WebUtility.GetPhysicalFilePath(string.Format("~/Themes/{0}/{1}", presentAreaKey, themeKey)); //移动目录 if (Directory.Exists(themePath)) { Directory.Delete(themePath, true); } parentDirectory.MoveTo(themePath); if (Directory.Exists(tempPath)) { Directory.Delete(tempPath, true); } } else { string[] appearanceConfigFileNames = Directory.GetFiles(tempPath, "Appearance.config", SearchOption.AllDirectories); if (appearanceConfigFileNames != null && appearanceConfigFileNames.Length > 0) { string appearanceConfigFileName = appearanceConfigFileNames[0]; XElement appearanceDocument = XElement.Load(appearanceConfigFileName); if (appearanceDocument == null) { Directory.Delete(tempPath, true); throw new ExceptionFacade("Appearance.config配置文件格式不正确"); } //获取父级目录 var parentDirectory = Directory.GetParent(appearanceConfigFileName); ThemeAppearance themeAppearance = new ThemeAppearance(appearanceDocument, parentDirectory.Name); themeAppearance.DisplayOrder = GetThemeAppearances(presentAreaKey, null).Max(n => n.DisplayOrder) + 1; string appearancesPath = WebUtility.GetPhysicalFilePath(string.Format("~/Themes/{0}/{1}/Appearances/", presentAreaKey, themeAppearance.ThemeKey)); //更新数据库 if (appearanceRepository.Get(themeAppearance.Id) != null) { appearanceRepository.Update(themeAppearance); } else { appearanceRepository.Insert(themeAppearance); } string appearancePath = Path.Combine(appearancesPath, themeAppearance.AppearanceKey); //移动目录 if (Directory.Exists(appearancePath)) { Directory.Delete(appearancePath, true); } parentDirectory.MoveTo(appearancePath); if (Directory.Exists(tempPath)) { Directory.Delete(tempPath, true); } } else { Directory.Delete(tempPath, true); throw new ExceptionFacade("找不到Appearance.config文件,您上传的不是皮肤包"); } } }
/// <summary> /// 新建实体时使用 /// </summary> /// <param name="presentAreaKey"></param> /// <param name="themeKey"></param> /// <param name="appearanceKey"></param> /// <param name="name"></param> /// <param name="previewImage"></param> /// <returns></returns> public static ThemeAppearance New(string presentAreaKey, string themeKey, string appearanceKey, string name, string previewImage) { ThemeAppearance themeAppearance = new ThemeAppearance() { PresentAreaKey = presentAreaKey, ThemeKey = themeKey, AppearanceKey = appearanceKey, Id = string.Format("{0},{1},{2}", presentAreaKey, themeKey, appearanceKey), Name = name, PreviewImage = previewImage, PreviewLargeImage = string.Empty, //LogoFileName = string.Empty, Description = string.Empty, Tags = string.Empty, Author = string.Empty, Copyright = string.Empty, LastModified = DateTime.UtcNow, Version = string.Empty, ForProductVersion = string.Empty, DateCreated = DateTime.UtcNow, Roles = string.Empty }; return themeAppearance; }
/// <summary> /// 构造函数 /// </summary> /// <param name="controllerContext"></param> /// <param name="viewPath"></param> /// <param name="layoutPath"></param> /// <param name="isPartialView"></param> /// <param name="applicationKey"></param> /// <param name="findLayoutPathOfThemeDelegate"></param> /// <param name="themeAppearance"></param> /// <param name="viewPageActivator"></param> public ThemedRazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool isPartialView, string applicationKey, Func <ThemeAppearance, string, string, string> findLayoutPathOfThemeDelegate, ThemeAppearance themeAppearance, IViewPageActivator viewPageActivator) : base(controllerContext, viewPath, viewPageActivator) { IsPartialView = isPartialView; ApplicationKey = applicationKey; if (!IsPartialView) { if (!string.IsNullOrEmpty(layoutPath)) { OverridenLayoutPath = layoutPath; } else { OverridenLayoutPath = string.Empty; ThemeAppearance = themeAppearance; FindLayoutPathOfThemeDelegate = findLayoutPathOfThemeDelegate; } } }
/// <summary> /// 获取Layout具体地址 /// </summary> /// <param name="themeAppearance"></param> /// <param name="layoutName">布局文件名称不要带.cshtml</param> /// <param name="applicationKey">应用模块标识</param> private string GetLayoutPathOfTheme(ThemeAppearance themeAppearance, string layoutName, string applicationKey) { if (string.IsNullOrEmpty(layoutName)) { return(String.Empty); } bool isFromApplication = !string.IsNullOrEmpty(applicationKey); StringBuilder cacheKeyBuilder = new StringBuilder("layoutPath:"); cacheKeyBuilder.Append(themeAppearance.PresentAreaKey); cacheKeyBuilder.AppendFormat(",{0}", themeAppearance.ThemeKey); cacheKeyBuilder.AppendFormat(",{0}", themeAppearance.PresentAreaKey); cacheKeyBuilder.AppendFormat(",{0}", layoutName); if (isFromApplication) { cacheKeyBuilder.AppendFormat(",{0}", applicationKey); } string cacheKey = cacheKeyBuilder.ToString(); ICacheService cacheService = DIContainer.Resolve <ICacheService>(); string layoutPath = cacheService.Get <string>(cacheKey); if (layoutPath == null) { if (IsSpecificPath(layoutName)) { layoutPath = GetPathFromSpecificName(layoutName); } else { List <string> layoutLocations = new List <string>(); if (isFromApplication) { layoutLocations.Add(string.Format("~/Applications/{1}/Layouts/{0}.cshtml", layoutName, applicationKey)); } //{2}:PresentAreaKey,{1}:ThemeKey,{0}:LayoutName layoutLocations.Add(string.Format("~/Themes/{2}/{1}/Layouts/{0}.cshtml", layoutName, themeAppearance.ThemeKey, themeAppearance.PresentAreaKey)); //如果Theme有Parent,则把Parent的路径也作为查找路径 Theme theme = ThemeService.GetTheme(themeAppearance.PresentAreaKey, themeAppearance.ThemeKey); if (!string.IsNullOrEmpty(theme.Parent)) { layoutLocations.Add(string.Format("~/Themes/{2}/{1}/Layouts/{0}.cshtml", layoutName, theme.Parent, themeAppearance.PresentAreaKey)); } //在呈现区域的公共Layouts路径查找 layoutLocations.Add(string.Format("~/Themes/{1}/Layouts/{0}.cshtml", layoutName, themeAppearance.PresentAreaKey)); //最后在~/Themes/Shared/Views/中查找 layoutLocations.Add(string.Format("~/Themes/Shared/Views/{0}.cshtml", layoutName)); foreach (var viewLocation in layoutLocations) { if (VirtualPathProvider.FileExists(viewLocation)) { layoutPath = viewLocation; break; } } } if (layoutPath != null) { cacheService.Add(cacheKey, layoutPath, CachingExpirationType.Stable); } } if (layoutPath == null) { throw new ExceptionFacade(new ResourceExceptionDescriptor("The LayoutName {0} could not be found!", layoutName)); } return(layoutPath); }
/// <summary> /// 获取应用模块中的ViewPath /// </summary> /// <remarks> /// 应用模块以外的功能View定位忽略Area /// </remarks> /// <param name="themeAppearance"></param> /// <param name="viewName"></param> /// <param name="controllerName"></param> /// <returns></returns> private string GetViewPathOfTheme(ThemeAppearance themeAppearance, string viewName, string controllerName) { StringBuilder cacheKeyBuilder = new StringBuilder("viewPath:"); cacheKeyBuilder.Append(themeAppearance.PresentAreaKey); cacheKeyBuilder.AppendFormat(",{0}", themeAppearance.ThemeKey); cacheKeyBuilder.AppendFormat(",{0}", controllerName); cacheKeyBuilder.AppendFormat(",{0}", viewName); string cacheKey = cacheKeyBuilder.ToString(); ICacheService cacheService = DIContainer.Resolve <ICacheService>(); string viewPath = cacheService.Get <string>(cacheKey); if (viewPath == null) { if (IsSpecificPath(viewName)) { viewPath = GetPathFromSpecificName(viewName); } else { //{3}:PresentAreaKey,{2}:ThemeKey,{1}:ControllerName,{0}:ViewName List <string> viewLocations = new List <string>(); viewLocations.Add(string.Format("~/Themes/{3}/{2}/Views/{1}/{0}.cshtml", viewName, controllerName, themeAppearance.ThemeKey, themeAppearance.PresentAreaKey)); //如果Theme有Parent,则把Parent的路径也作为查找路径 Theme theme = ThemeService.GetTheme(themeAppearance.PresentAreaKey, themeAppearance.ThemeKey); if (!string.IsNullOrEmpty(theme.Parent)) { viewLocations.Add(string.Format("~/Themes/{3}/{2}/Views/{1}/{0}.cshtml", viewName, controllerName, theme.Parent, themeAppearance.PresentAreaKey)); } //最后在~/Themes/Shared/Views/中查找 viewLocations.Add(string.Format("~/Themes/Shared/Views/{0}.cshtml", viewName)); foreach (var viewLocation in viewLocations) { if (VirtualPathProvider.FileExists(viewLocation)) { viewPath = viewLocation; break; } } } if (viewPath != null) { cacheService.Add(cacheKey, viewPath, CachingExpirationType.Stable); } } if (viewPath == null) { throw new ExceptionFacade(new ResourceExceptionDescriptor("The ViewName {0} Of the controllerName {0} could not be found!", viewName, controllerName)); } return(viewPath); }