Example #1
0
 /// <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;
         }
     }
 }
Example #2
0
        /// <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;
        }
Example #3
0
        /// <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;
        }
Example #4
0
        /// <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文件,您上传的不是皮肤包");
                }
            }
        }
Example #5
0
        /// <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文件,您上传的不是皮肤包");
                }
            }
        }
Example #6
0
        /// <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;
        }
Example #7
0
 /// <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;
         }
     }
 }
Example #8
0
        /// <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);
        }
Example #9
0
        /// <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);
        }