/// <summary> /// Used to create or update a 'partialview', 'partialviewmacro', 'script' or 'stylesheets' file /// </summary> /// <param name="display"></param> /// <returns>The updated CodeFileDisplay model</returns> public ActionResult <CodeFileDisplay> PostSave(CodeFileDisplay display) { if (display == null) { throw new ArgumentNullException(nameof(display)); } TryValidateModel(display); if (ModelState.IsValid == false) { return(ValidationProblem(ModelState)); } if (!display.IsConfigurationFile()) { return(NotFound()); } // if the file is the root web.config file, save a backup. var result = UpdateFile(display); if (result.Success) { return(result.Result); } display.AddErrorNotification( _localizedTextService.Localize("speechBubbles/configFileErrorHeader"), _localizedTextService.Localize("speechBubbles/configFileErrorText")); return(display); }
// Umbraco.Code.MapAll -FileType -Notifications -Path -Snippet private static void Map(IStylesheet source, CodeFileDisplay target, MapperContext context) { target.Content = source.Content; target.Id = source.Id.ToString(); target.Name = source.Name; target.VirtualPath = source.VirtualPath; }
public CodeFileDisplay GetByPath(string virtualPath) { if (string.IsNullOrWhiteSpace(virtualPath)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(virtualPath)); } virtualPath = HttpUtility.UrlDecode(virtualPath); var themeFile = new FileInfo(Path.Combine(IOHelper.MapPath(PathHelper.VirtualThemePath), virtualPath.Replace("/", "\\"))); //var script = Services.FileService.GetScriptByName(virtualPath); if (themeFile.Exists) { using (var reader = themeFile.OpenText()) { var display = new CodeFileDisplay { Content = reader.ReadToEnd(), FileType = themeFile.Extension, Id = HttpUtility.UrlEncode(virtualPath), Name = themeFile.Name, Path = GetTreePathFromFilePath(Url, virtualPath), VirtualPath = PathHelper.ThemePath.EnsureEndsWith('/') + virtualPath }; display.FileType = "ArticulateThemeFile"; return(display); } } throw new HttpResponseException(HttpStatusCode.NotFound); }
/// <summary> /// Create or Update a Script /// </summary> /// <param name="display"></param> /// <returns></returns> /// <remarks> /// It's important to note that Scripts are DIFFERENT from cshtml files since scripts use IFileSystem and cshtml files /// use a normal file system because they must exist on a real file system for ASP.NET to work. /// </remarks> private Script CreateOrUpdateScript(CodeFileDisplay display) { return(CreateOrUpdateFile(display, ".js", Current.FileSystems.ScriptsFileSystem, name => Services.FileService.GetScriptByName(name), (script, userId) => Services.FileService.SaveScript(script, userId), name => new Script(name))); }
public HttpResponseMessage PostCreate(string type, CodeFileDisplay display) { if (display == null) { throw new ArgumentNullException("display"); } if (string.IsNullOrWhiteSpace(type)) { throw new ArgumentException("Value cannot be null or whitespace.", "type"); } switch (type) { case Core.Constants.Trees.PartialViews: var view = new PartialView(PartialViewType.PartialView, display.VirtualPath); view.Content = display.Content; var result = Services.FileService.CreatePartialView(view, display.Snippet, Security.CurrentUser.Id); return(result.Success == true?Request.CreateResponse(HttpStatusCode.OK) : Request.CreateNotificationValidationErrorResponse(result.Exception.Message)); case Core.Constants.Trees.PartialViewMacros: var viewMacro = new PartialView(PartialViewType.PartialViewMacro, display.VirtualPath); viewMacro.Content = display.Content; var resultMacro = Services.FileService.CreatePartialViewMacro(viewMacro, display.Snippet, Security.CurrentUser.Id); return(resultMacro.Success == true?Request.CreateResponse(HttpStatusCode.OK) : Request.CreateNotificationValidationErrorResponse(resultMacro.Exception.Message)); case Core.Constants.Trees.Scripts: var script = new Script(display.VirtualPath); Services.FileService.SaveScript(script, Security.CurrentUser.Id); return(Request.CreateResponse(HttpStatusCode.OK)); default: return(Request.CreateResponse(HttpStatusCode.NotFound)); } }
private void CreateOrUpdateFile(string expectedExtension, CodeFileDisplay display) { display.VirtualPath = EnsureCorrectFileExtension(NormalizeVirtualPath(display.VirtualPath, PathHelper.VirtualThemePath), expectedExtension); display.Name = EnsureCorrectFileExtension(display.Name, expectedExtension); //if the name has changed we need to delete and re-create if (!Path.GetFileNameWithoutExtension(display.VirtualPath).InvariantEquals(Path.GetFileNameWithoutExtension(display.Name))) { //remove the original file _themesFileSystem.DeleteFile(display.VirtualPath); //now update the virtual path to be correct var parts = display.VirtualPath.Split('/'); display.VirtualPath = string.Join("/", parts.Take(parts.Length - 1)).EnsureEndsWith('/') + display.Name; } using (var stream = new MemoryStream()) using (var writer = new StreamWriter(stream)) { writer.Write(display.Content); writer.Flush(); //create or overwrite it _themesFileSystem.AddFile(display.VirtualPath.TrimStart('/'), stream, true); } }
public CodeFileDisplay PostSaveThemeFile(CodeFileDisplay themeFile) { if (themeFile == null) { throw new ArgumentNullException("themeFile"); } if (ModelState.IsValid == false) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); } switch (themeFile.FileType) { case "css": CreateOrUpdateFile(".css", themeFile); break; case "js": CreateOrUpdateFile(".js", themeFile); break; case "cshtml": CreateOrUpdateFile(".cshtml", themeFile); break; default: throw new HttpResponseException(HttpStatusCode.NotFound); } return(MapFromVirtualPath(themeFile.VirtualPath)); }
/// <summary> /// Helper method to take care of persisting partial views or partial view macros - so we're not duplicating the same logic /// </summary> /// <param name="display"></param> /// <param name="systemDirectory"></param> /// <param name="getView"></param> /// <param name="saveView"></param> /// <param name="createView"></param> /// <returns></returns> private Attempt <IPartialView> CreateOrUpdatePartialView( CodeFileDisplay display, string systemDirectory, Func <string, IPartialView> getView, Func <IPartialView, int, Attempt <IPartialView> > saveView, Func <IPartialView, string, int, Attempt <IPartialView> > createView) { //must always end with the correct extension display.Name = EnsureCorrectFileExtension(display.Name, ".cshtml"); Attempt <IPartialView> partialViewResult; var virtualPath = NormalizeVirtualPath(display.VirtualPath, systemDirectory); var view = getView(virtualPath); if (view != null) { // might need to find the path var orgPath = view.OriginalPath.Substring(0, view.OriginalPath.IndexOf(view.Name)); view.Path = orgPath + display.Name; view.Content = display.Content; partialViewResult = saveView(view, Security.CurrentUser.Id); } else { view = new PartialView(PartialViewType.PartialView, virtualPath + display.Name); view.Content = display.Content; partialViewResult = createView(view, display.Snippet, Security.CurrentUser.Id); } return(partialViewResult); }
private void CreateOrUpdateFile(CodeFileDisplay file) { // if the file is the root web.config file, save a backup of the original. if (file.VirtualPath.InvariantEndsWith("web.config")) { _fileSystem.CopyFile(file.VirtualPath, $"{file.VirtualPath}.{DateTime.Now:yyyyMMdd-HHmmss}"); } // file.VirtualPath = file.VirtualPath.EnsureCorrectFileExtension(configFileExtension); // file.Name = file.Name.EnsureCorrectFileExtension(configFileExtension); //if (!Path.GetFileNameWithoutExtension(file.VirtualPath).InvariantEquals(Path.GetFileNameWithoutExtension(file.Name))) //{ // _themesFileSystem.DeleteFile(file.VirtualPath); // string[] strArray = file.VirtualPath.Split('/'); // file.VirtualPath = string.Join("/", ((IEnumerable<string>)strArray).Take(strArray.Length - 1)).EnsureEndsWith('/') + file.Name; //} using (MemoryStream memoryStream = new MemoryStream()) { using (StreamWriter streamWriter = new StreamWriter(memoryStream)) { streamWriter.Write(file.Content); streamWriter.Flush(); _fileSystem.AddFile(file.VirtualPath.TrimStart('/'), memoryStream, true); } } }
/// <summary> /// Create or Update a Script /// </summary> /// <param name="display"></param> /// <returns></returns> /// <remarks> /// It's important to note that Scripts are DIFFERENT from cshtml files since scripts use IFileSystem and cshtml files /// use a normal file system because they must exist on a real file system for ASP.NET to work. /// </remarks> private IScript?CreateOrUpdateScript(CodeFileDisplay display) { return(CreateOrUpdateFile(display, ".js", _fileSystems.ScriptsFileSystem, name => _fileService.GetScript(name), (script, userId) => _fileService.SaveScript(script, userId), name => new Script(name ?? string.Empty))); }
private Stylesheet CreateOrUpdateStylesheet(CodeFileDisplay display) { return(CreateOrUpdateFile(display, ".css", Current.FileSystems.StylesheetsFileSystem, name => Services.FileService.GetStylesheetByName(name), (stylesheet, userId) => Services.FileService.SaveStylesheet(stylesheet, userId), name => new Stylesheet(name) )); }
private IStylesheet?CreateOrUpdateStylesheet(CodeFileDisplay display) => CreateOrUpdateFile( display, ".css", _fileSystems.StylesheetsFileSystem, name => _fileService.GetStylesheet(name), (stylesheet, userId) => _fileService.SaveStylesheet(stylesheet, userId), name => new Stylesheet(name ?? string.Empty));
public ActionResult <CodeFileDisplay> PostCreate(string type, CodeFileDisplay display) { if (display == null) { throw new ArgumentNullException("display"); } if (string.IsNullOrWhiteSpace(type)) { throw new ArgumentException("Value cannot be null or whitespace.", "type"); } IUser?currentUser = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser; switch (type) { case Constants.Trees.PartialViews: var view = new PartialView(PartialViewType.PartialView, display.VirtualPath ?? string.Empty) { Content = display.Content, }; Attempt <IPartialView?> result = _fileService.CreatePartialView(view, display.Snippet, currentUser?.Id); if (result.Success) { return(Ok()); } return(ValidationProblem(result.Exception?.Message)); case Constants.Trees.PartialViewMacros: var viewMacro = new PartialView(PartialViewType.PartialViewMacro, display.VirtualPath ?? string.Empty) { Content = display.Content, }; Attempt <IPartialView?> resultMacro = _fileService.CreatePartialViewMacro(viewMacro, display.Snippet, currentUser?.Id); if (resultMacro.Success) { return(Ok()); } return(ValidationProblem(resultMacro.Exception?.Message)); case Constants.Trees.Scripts: var script = new Script(display.VirtualPath ?? string.Empty); _fileService.SaveScript(script, currentUser?.Id); return(Ok()); default: return(NotFound()); } }
/// <summary> /// Creates a CodeFileDisplay object from a virtual filesystem path. /// </summary> /// <param name="fileSystem"></param> /// <param name="path"></param> /// <returns></returns> internal static CodeFileDisplay PathToCodeFile(this IFileSystem fileSystem, string path) { using (StreamReader streamReader = new StreamReader(fileSystem.OpenFile(path))) { CodeFileDisplay codeFileDisplay = new CodeFileDisplay { Content = streamReader.ReadToEnd(), FileType = Path.GetExtension(path), Id = HttpUtility.UrlEncode(path), Name = Path.GetFileName(path), Path = path.ToTree(), VirtualPath = path }; codeFileDisplay.FileType = Path.GetExtension(path).TrimStart('.'); return(codeFileDisplay); } }
private CodeFileDisplay MapFromVirtualPath(string virtualPath) { using (var reader = new StreamReader(_themesFileSystem.OpenFile(virtualPath))) { var display = new CodeFileDisplay { Content = reader.ReadToEnd(), FileType = Path.GetExtension(virtualPath), Id = HttpUtility.UrlEncode(virtualPath), Name = Path.GetFileName(virtualPath), Path = Url.GetTreePathFromFilePath(virtualPath), VirtualPath = NormalizeVirtualPath(virtualPath, PathHelper.VirtualThemePath) }; display.FileType = Path.GetExtension(virtualPath).TrimStart('.'); return(display); } }
private T CreateOrUpdateFile <T>(CodeFileDisplay display, string extension, IFileSystem fileSystem, Func <string, T> getFileByName, Action <T, int> saveFile, Func <string, T> createFile) where T : Core.Models.File { //must always end with the correct extension display.Name = EnsureCorrectFileExtension(display.Name, extension); var virtualPath = display.VirtualPath ?? string.Empty; // this is all weird, should be using relative paths everywhere! var relPath = fileSystem.GetRelativePath(virtualPath); if (relPath.EndsWith(extension) == false) { //this would typically mean it's new relPath = relPath.IsNullOrWhiteSpace() ? relPath + display.Name : relPath.EnsureEndsWith('/') + display.Name; } var file = getFileByName(relPath); if (file != null) { // might need to find the path var orgPath = file.OriginalPath.Substring(0, file.OriginalPath.IndexOf(file.Name)); file.Path = orgPath + display.Name; file.Content = display.Content; //try/catch? since this doesn't return an Attempt? saveFile(file, Security.CurrentUser.Id); } else { file = createFile(relPath); file.Content = display.Content; saveFile(file, Security.CurrentUser.Id); } return(file); }
public CodeFileDisplay SaveFile(CodeFileDisplay file) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (!ModelState.IsValid) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); } if (!FileExtensions.InvariantContains(file.FileType)) { throw new HttpResponseException(HttpStatusCode.NotFound); } // if the file is the root web.config file, save a backup. CreateOrUpdateFile(file); return(_fileSystem.PathToCodeFile(file.VirtualPath)); }
private Attempt <CodeFileDisplay> UpdateFile(CodeFileDisplay file) { // if the file is an appsettings.json file, save a backup of the original. if (file.VirtualPath.InvariantEndsWith("appsettings.json")) { _fileSystem.CopyFile(file.VirtualPath, $"{file.VirtualPath}.{DateTime.Now:yyyyMMdd-HHmmss}"); } // file.VirtualPath = file.VirtualPath.EnsureCorrectFileExtension(configFileExtension); // file.Name = file.Name.EnsureCorrectFileExtension(configFileExtension); //if (!Path.GetFileNameWithoutExtension(file.VirtualPath).InvariantEquals(Path.GetFileNameWithoutExtension(file.Name))) //{ // _themesFileSystem.DeleteFile(file.VirtualPath); // string[] strArray = file.VirtualPath.Split('/'); // file.VirtualPath = string.Join("/", ((IEnumerable<string>)strArray).Take(strArray.Length - 1)).EnsureEndsWith('/') + file.Name; //} Attempt <CodeFileDisplay> attempt; try { using (MemoryStream memoryStream = new()) { using StreamWriter streamWriter = new(memoryStream); streamWriter.Write(file.Content); streamWriter.Flush(); _fileSystem.AddFile(file.VirtualPath.TrimStart('/'), memoryStream, true); } attempt = Attempt <CodeFileDisplay> .Succeed(file); } catch (IOException ioe) { _logger.LogError(ioe, "Could not save file {file}", file.Path); attempt = Attempt <CodeFileDisplay> .Fail(); } return(attempt); }
/// <summary> /// Create or Update a Script /// </summary> /// <param name="display"></param> /// <returns></returns> /// <remarks> /// It's important to note that Scripts are DIFFERENT from cshtml files since scripts use IFileSystem and cshtml files /// use a normal file system because they must exist on a real file system for ASP.NET to work. /// </remarks> private Script CreateOrUpdateScript(CodeFileDisplay display) { //must always end with the correct extension display.Name = EnsureCorrectFileExtension(display.Name, ".js"); var virtualPath = display.VirtualPath ?? string.Empty; // this is all weird, should be using relative paths everywhere! var relPath = FileSystemProviderManager.Current.ScriptsFileSystem.GetRelativePath(virtualPath); if (relPath.EndsWith(".js") == false) { //this would typically mean it's new relPath = relPath.IsNullOrWhiteSpace() ? relPath + display.Name : relPath.EnsureEndsWith('/') + display.Name; } var script = Services.FileService.GetScriptByName(relPath); if (script != null) { // might need to find the path var orgPath = script.OriginalPath.Substring(0, script.OriginalPath.IndexOf(script.Name)); script.Path = orgPath + display.Name; script.Content = display.Content; //try/catch? since this doesn't return an Attempt? Services.FileService.SaveScript(script, Security.CurrentUser.Id); } else { script = new Script(relPath); script.Content = display.Content; Services.FileService.SaveScript(script, Security.CurrentUser.Id); } return(script); }
internal static bool IsConfigurationFile(this CodeFileDisplay file) { return(Constants.Plugin.FileExtensions.InvariantContains(file.FileType)); }
private Attempt <IPartialView> CreateOrUpdatePartialViewMacro(CodeFileDisplay display) { return(CreateOrUpdatePartialView(display, SystemDirectories.MacroPartials, Services.FileService.GetPartialViewMacro, Services.FileService.SavePartialViewMacro, Services.FileService.CreatePartialViewMacro)); }
public CodeFileDisplay PostCreateFile(string parentId, string name, string type) { //todo: what about paths? we need to know where we are if (string.IsNullOrWhiteSpace(parentId)) { throw new ArgumentException("Value cannot be null or whitespace.", "parentId"); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(name)); } if (string.IsNullOrWhiteSpace(type)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(type)); } // if the parentId is root (-1) then we just need an empty string as we are // creating the path below and we don't wan't -1 in the path if (parentId == Constants.System.Root.ToInvariantString()) { parentId = string.Empty; } name = HttpUtility.UrlDecode(name); var virtualPath = name; if (parentId.IsNullOrWhiteSpace() == false) { parentId = HttpUtility.UrlDecode(parentId); virtualPath = parentId.EnsureEndsWith("/") + name; } var codeFile = new CodeFileDisplay { VirtualPath = virtualPath, Name = name }; switch (type.ToLower()) { case "javascript": CreateOrUpdateFile(".js", codeFile); break; case "css": CreateOrUpdateFile(".css", codeFile); break; case "razor": CreateOrUpdateFile(".cshtml", codeFile); break; case "folder": virtualPath = NormalizeVirtualPath(virtualPath, PathHelper.VirtualThemePath); _themesFileSystem.CreateFolder(virtualPath); return(new CodeFileDisplay { VirtualPath = virtualPath, Path = Url.GetTreePathFromFilePath(virtualPath) }); default: throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); } return(MapFromVirtualPath(codeFile.VirtualPath)); }
/// <summary> /// Used to create or update a 'partialview', 'partialviewmacro', 'script' or 'stylesheets' file /// </summary> /// <param name="display"></param> /// <returns>The updated CodeFileDisplay model</returns> public CodeFileDisplay PostSave(CodeFileDisplay display) { if (display == null) { throw new ArgumentNullException("display"); } if (ModelState.IsValid == false) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); } switch (display.FileType) { case Core.Constants.Trees.PartialViews: var partialViewResult = CreateOrUpdatePartialView(display); if (partialViewResult.Success) { display = Mapper.Map(partialViewResult.Result, display); display.Path = Url.GetTreePathFromFilePath(partialViewResult.Result.Path); display.Id = System.Web.HttpUtility.UrlEncode(partialViewResult.Result.Path); return(display); } display.AddErrorNotification( Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), Services.TextService.Localize("speechBubbles/partialViewErrorText")); break; case Core.Constants.Trees.PartialViewMacros: var partialViewMacroResult = CreateOrUpdatePartialViewMacro(display); if (partialViewMacroResult.Success) { display = Mapper.Map(partialViewMacroResult.Result, display); display.Path = Url.GetTreePathFromFilePath(partialViewMacroResult.Result.Path); display.Id = System.Web.HttpUtility.UrlEncode(partialViewMacroResult.Result.Path); return(display); } display.AddErrorNotification( Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), Services.TextService.Localize("speechBubbles/partialViewErrorText")); break; case Core.Constants.Trees.Scripts: var scriptResult = CreateOrUpdateScript(display); display = Mapper.Map(scriptResult, display); display.Path = Url.GetTreePathFromFilePath(scriptResult.Path); display.Id = System.Web.HttpUtility.UrlEncode(scriptResult.Path); return(display); //display.AddErrorNotification( // Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), // Services.TextService.Localize("speechBubbles/partialViewErrorText")); case Core.Constants.Trees.Stylesheets: var stylesheetResult = CreateOrUpdateStylesheet(display); display = Mapper.Map(stylesheetResult, display); display.Path = Url.GetTreePathFromFilePath(stylesheetResult.Path); display.Id = System.Web.HttpUtility.UrlEncode(stylesheetResult.Path); return(display); default: throw new HttpResponseException(HttpStatusCode.NotFound); } return(display); }
private T CreateOrUpdateFile <T>(CodeFileDisplay display, string extension, IFileSystem?fileSystem, Func <string?, T> getFileByName, Action <T, int?> saveFile, Func <string?, T> createFile) where T : IFile? {
// Umbraco.Code.MapAll -CreateDate -DeleteDate -UpdateDate -GetFileContent // Umbraco.Code.MapAll -Id -Key -Alias -Name -OriginalPath -Path private static void Map(CodeFileDisplay source, IScript target, MapperContext context) { target.Content = source.Content; target.VirtualPath = source.VirtualPath; }
/// <summary> /// Used to create or update a 'partialview', 'partialviewmacro', 'script' or 'stylesheets' file /// </summary> /// <param name="display"></param> /// <returns>The updated CodeFileDisplay model</returns> public ActionResult <CodeFileDisplay> PostSave(CodeFileDisplay display) { if (display == null) { throw new ArgumentNullException("display"); } TryValidateModel(display); if (ModelState.IsValid == false) { return(ValidationProblem(ModelState)); } switch (display.FileType) { case Constants.Trees.PartialViews: Attempt <IPartialView?> partialViewResult = CreateOrUpdatePartialView(display); if (partialViewResult.Success) { display = _umbracoMapper.Map(partialViewResult.Result, display); display.Path = Url.GetTreePathFromFilePath(partialViewResult.Result?.Path); display.Id = HttpUtility.UrlEncode(partialViewResult.Result?.Path); return(display); } display.AddErrorNotification( _localizedTextService.Localize("speechBubbles", "partialViewErrorHeader"), _localizedTextService.Localize("speechBubbles", "partialViewErrorText")); break; case Constants.Trees.PartialViewMacros: Attempt <IPartialView?> partialViewMacroResult = CreateOrUpdatePartialViewMacro(display); if (partialViewMacroResult.Success) { display = _umbracoMapper.Map(partialViewMacroResult.Result, display); display.Path = Url.GetTreePathFromFilePath(partialViewMacroResult.Result?.Path); display.Id = HttpUtility.UrlEncode(partialViewMacroResult.Result?.Path); return(display); } display.AddErrorNotification( _localizedTextService.Localize("speechBubbles", "partialViewErrorHeader"), _localizedTextService.Localize("speechBubbles", "partialViewErrorText")); break; case Constants.Trees.Scripts: IScript?scriptResult = CreateOrUpdateScript(display); display = _umbracoMapper.Map(scriptResult, display); display.Path = Url.GetTreePathFromFilePath(scriptResult?.Path); display.Id = HttpUtility.UrlEncode(scriptResult?.Path); return(display); //display.AddErrorNotification( // _localizedTextService.Localize("speechBubbles/partialViewErrorHeader"), // _localizedTextService.Localize("speechBubbles/partialViewErrorText")); case Constants.Trees.Stylesheets: IStylesheet?stylesheetResult = CreateOrUpdateStylesheet(display); display = _umbracoMapper.Map(stylesheetResult, display); display.Path = Url.GetTreePathFromFilePath(stylesheetResult?.Path); display.Id = HttpUtility.UrlEncode(stylesheetResult?.Path); return(display); default: return(NotFound()); } return(display); }
private Attempt <IPartialView> CreateOrUpdatePartialView(CodeFileDisplay display) { return(CreateOrUpdatePartialView(display, Constants.SystemDirectories.PartialViews, _fileService.GetPartialView, _fileService.SavePartialView, _fileService.CreatePartialView)); }