public static void DeleteProduct(CMSDatabase db, int?productID, HttpContext context, out bool successfullyDeleted) { if (!productID.HasValue) { successfullyDeleted = false; return; } ProductPage product = db.ProductPages.FirstOrDefault(pp => pp.ID == productID.Value); if (product == null) { successfullyDeleted = false; return; } IHostingEnvironment env = context.RequestServices.GetRequiredService <IHostingEnvironment>(); string pathToImages = $"{env.GetProductsImagesFolderFullPath()}{product.ID}/"; // Удаляем данные об изображениях из БД string[] images = ImagesManagementFunctions.GetProductImageUrls(product, env); for (int i = 0; i < images.Length; ++i) { Image image = db.Images.FirstOrDefault(img => img.ShortPathHash == OtherFunctions.GetHashFromString(images[i]) && img.ShortPath.Equals(images[i], StringComparison.Ordinal)); if (image != null) { db.Images.Remove(image); } } db.Entry(product).Reference(pp => pp.PreviousPage).Load(); --product.PreviousPage.ProductsCount; db.ProductPages.Remove(product); db.SaveChanges(); // Удаляем папку с изображениями товара if (Directory.Exists(pathToImages)) { Directory.Delete(pathToImages, true); } successfullyDeleted = true; LogManagementFunctions.AddAdminPanelLog( db: db, context: context, info: $"{product.PageName} (ID-{product.ID.ToString()}): {(context.Items["LogLocalization"] as IAdminPanelLogLocalization)?.ProductDeleted}" ); }
public IActionResult ProductImages(int?itemID) { HttpContext.Items["pageID"] = AdminPanelPages.ProductImages; if (!itemID.HasValue) { return(Redirect($"{HttpContext.Request.Path}?pageID={(int)AdminPanelPages.Categories}")); } ProductPage product = db.ProductPages.AsNoTracking().FirstOrDefault(pp => pp.ID == itemID); if (product == null) { return(Redirect($"{HttpContext.Request.Path}?pageID={(int)AdminPanelPages.Categories}")); } IHostingEnvironment env = HttpContext.RequestServices.GetService <IHostingEnvironment>(); string[] productImages = ImagesManagementFunctions.GetProductImageUrls(product, env); HttpContext.Items["ProductPage"] = product; return(View("CategoriesAndProducts/ProductImages", productImages)); }
public IActionResult AdminPanel(AdminPanelPages pageID, int?itemID, string path, IFormFile uploadedFile) { AccessLevelConfiguration accessLevelConfiguration = HttpContext.RequestServices.GetService <AccessLevelConfiguration>(); HttpContext.Items["AccessLevelConfiguration"] = accessLevelConfiguration; User user = SecurityFunctions.CheckCookies(db, HttpContext); if (!SecurityFunctions.HasAccessTo(pageID, user, HttpContext)) { return(RedirectToAction(nameof(AdminPanel))); } HttpContext.Items["User"] = user; HttpContext.Items["LogLocalization"] = localization; switch (pageID) { case AdminPanelPages.AddProductImage: ImagesManagementFunctions.UploadProductImageToServer(db, uploadedFile, itemID, HttpContext, out bool successfullyUploadedImage); if (successfullyUploadedImage) { return(StatusCode(200)); } else { return(StatusCode(415)); } case AdminPanelPages.UploadFile: FileManagerManagementFunctions.UploadFileToServer(db, path, uploadedFile, HttpContext, out bool successfullyUploadedFile); if (successfullyUploadedFile) { return(StatusCode(200)); } else { return(StatusCode(415)); } default: return(RedirectToAction(nameof(AdminPanel))); } }
public static void DeletePage(CMSDatabase db, PageType?pageType, int?itemID, HttpContext context, out bool successfullyDeleted) { if (!pageType.HasValue || !itemID.HasValue) { successfullyDeleted = false; return; } Page page = null; switch (pageType) { case PageType.Usual: page = db.UsualPages.FirstOrDefault(p => p.ID == itemID); break; case PageType.Category: page = db.CategoryPages.FirstOrDefault(p => p.ID == itemID); break; default: successfullyDeleted = false; return; } if (page == null) { successfullyDeleted = false; return; } if (page is UsualPage up) { // Получаем все зависимые страницы List <UsualPage> usualPages = db.UsualPages.Where(p => p.PreviousPageID == up.ID).ToList(); List <CategoryPage> categoryPages = db.CategoryPages.Where(p => p.PreviousPageID == up.ID).ToList(); db.UsualPages.Remove(up); db.SaveChanges(); // Обновляем полученные зависимые страницы foreach (var u_page in usualPages) { u_page.PreviousPageID = up.PreviousPageID; RefreshPageAndDependencies(db, u_page); } foreach (var c_page in categoryPages) { c_page.PreviousPageID = up.PreviousPageID; RefreshPageAndDependencies(db, c_page); } } else if (page is CategoryPage cp) { IHostingEnvironment env = context.RequestServices.GetRequiredService <IHostingEnvironment>(); cp.ProductPages = db.ProductPages.Where(pp => pp.PreviousPageID == cp.ID).ToList(); foreach (var p in cp.ProductPages) { string[] images = ImagesManagementFunctions.GetProductImageUrls(p, env); for (int i = 0; i < images.Length; ++i) { Image image = db.Images.FirstOrDefault(img => img.ShortPathHash == OtherFunctions.GetHashFromString(images[i]) && img.ShortPath.Equals(images[i], StringComparison.Ordinal)); if (image != null) { db.Images.Remove(image); } } string pathToImages = $"{env.GetProductsImagesFolderFullPath()}{p.ID}/"; if (Directory.Exists(pathToImages)) { Directory.Delete(pathToImages, true); } } db.Remove(page); } db.SaveChanges(); successfullyDeleted = true; LogManagementFunctions.AddAdminPanelLog( db: db, context: context, info: $"{page.PageName} (ID-{page.ID.ToString()}): " + (page is UsualPage ? (context.Items["LogLocalization"] as IAdminPanelLogLocalization)?.PageDeleted : (context.Items["LogLocalization"] as IAdminPanelLogLocalization)?.CategoryDeleted) ); }
public IActionResult AdminPanel(AdminPanelPages pageID, int?itemID, int?imageID, string path) { AccessLevelConfiguration accessLevelConfiguration = HttpContext.RequestServices.GetService <AccessLevelConfiguration>(); HttpContext.Items["AccessLevelConfiguration"] = accessLevelConfiguration; User user = SecurityFunctions.CheckCookies(db, HttpContext); if (pageID == AdminPanelPages.Exit) { DatabaseInteraction.Exit(db, user, HttpContext, out int exitStatusCode); return(StatusCode(exitStatusCode)); } if (!SecurityFunctions.HasAccessTo(pageID, user, HttpContext)) { return(RedirectToAction(nameof(AdminPanel))); } HttpContext.Items["User"] = user; HttpContext.Items["LogLocalization"] = localization; switch (pageID) { case AdminPanelPages.DeletePage: DatabaseInteraction.DeletePage(db, PageType.Usual, itemID, HttpContext, out bool pageDeleted); if (pageDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteCategory: DatabaseInteraction.DeletePage(db, PageType.Category, itemID, HttpContext, out bool categoryDeleted); if (categoryDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteProduct: DatabaseInteraction.DeleteProduct(db, itemID, HttpContext, out bool productDeleted); if (productDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteProductImage: ImagesManagementFunctions.DeleteProductImage(db, itemID, imageID, HttpContext, out bool productImageDeleted); if (productImageDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteRedirection: DatabaseInteraction.DeleteRedirection(db, itemID, HttpContext, out bool redirectionDeleted); if (redirectionDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteTemplate: DatabaseInteraction.DeleteTemplate(db, itemID, HttpContext, out bool templateDeleted); if (templateDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteChunk: DatabaseInteraction.DeleteChunk(db, itemID, HttpContext, out bool chunkDeleted); if (chunkDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteFileOrFolder: FileManagerManagementFunctions.DeleteFileOrFolder(db, path, HttpContext, out string redirectPath); if (redirectPath == null) { return(StatusCode(404)); } else { string redirectUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}?pageID={(int)AdminPanelPages.FileManager}&path={redirectPath}"; HttpContext.Response.Headers.Add("location", redirectUrl); return(StatusCode(200)); } case AdminPanelPages.DeleteUser: DatabaseInteraction.DeleteUser(db, itemID, HttpContext, out int userDeletionStatusCode); return(StatusCode(userDeletionStatusCode)); case AdminPanelPages.DeleteUserType: DatabaseInteraction.DeleteUserType(db, itemID, HttpContext, out bool userTypeDeleted); if (userTypeDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } case AdminPanelPages.DeleteSynonymForString: DatabaseInteraction.DeleteSynonymForString(db, itemID, HttpContext, out bool synonymForStringDeleted); if (synonymForStringDeleted) { return(StatusCode(200)); } else { return(StatusCode(404)); } default: return(RedirectToAction(nameof(AdminPanel))); } }
#pragma warning disable 1998 public async override global::System.Threading.Tasks.Task ExecuteAsync() { #line 2 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Dictionary <int, int> counters = new Dictionary <int, int>(); #line default #line hidden BeginContext(76, 58, true); WriteLiteral("<div class=\"content-block\">\n\t<div class=\"navigation-menu\">"); EndContext(); BeginContext(136, 72, false); #line 3 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(Model != null ? Html.Raw(Model.BreadcrumbsHtml) : Html.Raw(string.Empty)); #line default #line hidden EndContext(); BeginContext(209, 3, true); WriteLiteral(" → "); EndContext(); BeginContext(214, 65, false); #line 3 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(Model != null ? Html.Raw(Model.PageName) : Html.Raw(string.Empty)); #line default #line hidden EndContext(); BeginContext(280, 125, true); WriteLiteral("</div>\n\t<div class=\"container\">\n\t\t<div class=\"gallery\">\n\t\t\t<a class=\"selected-image-block\" data-lightbox=\"image\" data-title=\""); EndContext(); BeginContext(407, 65, false); #line 6 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(Model != null ? Html.Raw(Model.PageName) : Html.Raw(string.Empty)); #line default #line hidden EndContext(); BeginContext(473, 62, true); WriteLiteral("\"><img id=\"selected-image\"></a>\n\t\t\t<div id=\"image-container\">\n"); EndContext(); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" var env = Context.RequestServices.GetService(typeof(Microsoft.AspNetCore.Hosting.IHostingEnvironment)) as Microsoft.AspNetCore.Hosting.IHostingEnvironment; foreach (var imgUrl in ImagesManagementFunctions.GetProductImageUrls(Model as ProductPage, env, 0)) { #line default #line hidden BeginContext(806, 4, true); WriteLiteral("<div"); EndContext(); BeginWriteAttribute("id", " id=\"", 810, "\"", 908, 2); WriteAttributeValue("", 815, "image-", 815, 6, true); WriteAttributeValue("", 821, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => { PushWriter(__razor_attribute_value_writer); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" if (!counters.ContainsKey(1)) { counters.Add(1, 0); } #line default #line hidden BeginContext(885, 13, false); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(++counters[1]); #line default #line hidden EndContext(); PopWriter(); } ), 821, 87, false); EndWriteAttribute(); BeginContext(909, 1, true); WriteLiteral(">"); EndContext(); BeginContext(910, 77, false); __tagHelperExecutionContext = __tagHelperScopeManager.Begin("image", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "ae13e9542d7b38585970634c3d0f5cace5961edb8259", async() => { } ); __Treynessen_TagHelpers_ImageTagHelper = CreateTagHelper <global::Treynessen.TagHelpers.ImageTagHelper>(); __tagHelperExecutionContext.Add(__Treynessen_TagHelpers_ImageTagHelper); BeginWriteTagHelperAttribute(); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" WriteLiteral(imgUrl); #line default #line hidden __tagHelperStringValueBuffer = EndWriteTagHelperAttribute(); __Treynessen_TagHelpers_ImageTagHelper.Src = __tagHelperStringValueBuffer; __tagHelperExecutionContext.AddTagHelperAttribute("src", __Treynessen_TagHelpers_ImageTagHelper.Src, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" __Treynessen_TagHelpers_ImageTagHelper.MaxWidth = 350; #line default #line hidden __tagHelperExecutionContext.AddTagHelperAttribute("max-width", __Treynessen_TagHelpers_ImageTagHelper.MaxWidth, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" __Treynessen_TagHelpers_ImageTagHelper.MaxHeight = 270; #line default #line hidden __tagHelperExecutionContext.AddTagHelperAttribute("max-height", __Treynessen_TagHelpers_ImageTagHelper.MaxHeight, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" __Treynessen_TagHelpers_ImageTagHelper.Quality = 95; #line default #line hidden __tagHelperExecutionContext.AddTagHelperAttribute("quality", __Treynessen_TagHelpers_ImageTagHelper.Quality, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes); await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); if (!__tagHelperExecutionContext.Output.IsContentModified) { await __tagHelperExecutionContext.SetOutputContentAsync(); } Write(__tagHelperExecutionContext.Output); __tagHelperExecutionContext = __tagHelperScopeManager.End(); EndContext(); BeginContext(987, 6, true); WriteLiteral("</div>"); EndContext(); #line 8 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" } #line default #line hidden BeginContext(1005, 79, true); WriteLiteral("\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"info-container\">\n\t\t\t<div class=\"product-name\">"); EndContext(); BeginContext(1086, 65, false); #line 12 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(Model != null ? Html.Raw(Model.PageName) : Html.Raw(string.Empty)); #line default #line hidden EndContext(); BeginContext(1152, 47, true); WriteLiteral("</div>\n\t\t\t<div class=\"price\"><span>Цена:</span>"); EndContext(); BeginContext(1201, 336, false); #line 13 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(Model is ProductPage && (Model as ProductPage).OldPrice != 0 ? Html.Raw("<span>" + OtherFunctions.PriceFormatting((Model as ProductPage).Price) + "</span><span>" + OtherFunctions.PriceFormatting((Model as ProductPage).OldPrice) + "</span>") : Html.Raw("<span>" + OtherFunctions.PriceFormatting((Model as ProductPage).Price) + "</span>")); #line default #line hidden EndContext(); BeginContext(1538, 411, true); WriteLiteral(@"</div> <div class=""offer"">Если найдете цену ниже, мы предложим более выгодные условия!</div> <div class=""info"">Приходите! У нас огромный ассортимент инструмента, есть другие модели!</div> <div class=""info"">Звоните ежедневно с 11:00 до 17:00 по телефону <a href=""tel:89082905999"">8 9082 905-999</a></div> </div> </div> <div class=""description""> <div class=""tab"">Описание</div> <div class=""text"">" ); EndContext(); BeginContext(1951, 64, false); #line 21 "C:\Users\79622\Desktop\Github\StoreCMS\StoreCMS\Views\Chunks\product_page_content.cshtml" Write(Model != null ? Html.Raw(Model.Content) : Html.Raw(string.Empty)); #line default #line hidden EndContext(); BeginContext(2016, 22, true); WriteLiteral("</div>\n\t</div>\n</div>\n"); EndContext(); }
public static void EditProduct(CMSDatabase db, PageModel model, int?productID, HttpContext context, out bool successfullyCompleted) { if (model == null || !productID.HasValue) { successfullyCompleted = false; return; } model.PageType = PageType.Product; ProductPage editableProduct = db.ProductPages.AsNoTracking().FirstOrDefault(pp => pp.ID == productID.Value); if (editableProduct == null) { successfullyCompleted = false; return; } model.ID = editableProduct.ID; model.PreviousPageID = editableProduct.PreviousPageID; ProductPage editedProduct = PagesManagementFunctions.PageModelToPage(db, model, context) as ProductPage; if (editedProduct == null) { successfullyCompleted = false; return; } editedProduct.PreviousPage.LastProductTemplate = editedProduct.Template; db.ProductPages.Update(editedProduct); db.SaveChanges(); // Изменяем имена изображений продукта, если изменился псевдоним страницы if (!editableProduct.Alias.Equals(editedProduct.Alias, StringComparison.Ordinal)) { IHostingEnvironment env = context.RequestServices.GetRequiredService <IHostingEnvironment>(); string pathToImages = $"{env.GetProductsImagesFolderFullPath()}{editedProduct.ID}/"; if (Directory.Exists(pathToImages)) { string oldName = editableProduct.Alias; string newName = editedProduct.Alias; Regex imageChecker = new Regex($"{oldName}(_\\d+)?.jpg$"); string[] oldImagesNames = Directory.GetFiles(pathToImages, $"*{oldName}*.jpg"); string[] imagePaths = (from img in oldImagesNames where imageChecker.IsMatch(img) select img).ToArray(); // Можно было бы заменить разом имена всем изображениям через перебор в цикле, но // проблема в том, что путь до папки с изображениями может содержать старое название // изображения. В итоге замена имени через File.Move(старый_путь, старый_путь.Replace(oldName, newName)) // может привести к переносу изображений в другую директорию. LinkedList <KeyValuePair <string, string> > renameErrors = new LinkedList <KeyValuePair <string, string> >(); for (int i = 0; i < imagePaths.Length; ++i) { string oldImageName = imagePaths[i].Substring(pathToImages.Length, imagePaths[i].Length - pathToImages.Length - 4); string newImageName = oldImageName.Replace(oldName, newName); try { ImagesManagementFunctions.RenameImageAndDependencies( db: db, env: env, pathToImages: pathToImages, oldImageName: oldImageName, newImageName: newImageName, imageExtension: ".jpg", saveChangesInDB: false ); } catch (IOException) { // Добавляем все ошибки переименования в список для второй попытки. Например, старое название было // "Название" и мы переименовали страницу на "Название_2", но у товара было несколько картинок, // соответственно при ренейминге будет попытка присвоить первой картинке название Название_2, что приведет // к ошибке, т.к. картинка с таким названием уже существует. Поэтому после первого прохода сделаем второй, // что поможет избежать этих ошибок переименования renameErrors.AddLast(new KeyValuePair <string, string>(oldImageName, newImageName)); } } if (renameErrors.Count > 0) { foreach (var e in renameErrors) { ImagesManagementFunctions.RenameImageAndDependencies( db: db, env: env, pathToImages: pathToImages, oldImageName: e.Key, newImageName: e.Value, imageExtension: ".jpg", saveChangesInDB: false ); } } db.SaveChanges(); } } successfullyCompleted = true; LogManagementFunctions.AddAdminPanelLog( db: db, context: context, info: $"{editableProduct.PageName} (ID-{editableProduct.ID.ToString()}): {(context.Items["LogLocalization"] as IAdminPanelLogLocalization)?.ProductEdited}" ); }
public static void DeleteFileOrFolder(CMSDatabase db, string path, HttpContext context, out string redirectPath) { IHostingEnvironment env = context.RequestServices.GetService <IHostingEnvironment>(); Regex regex = new Regex(@"^((\w|-|_)+)(>(\w|-|_)+)*(\.\w+)?$"); if (!regex.IsMatch(path)) { redirectPath = null; return; } string fileOrFolderFullName = path.Substring(path.LastIndexOf('>') + 1); redirectPath = path = path.Substring(0, path.Length - fileOrFolderFullName.Length); if (!string.IsNullOrEmpty(path)) { path = path.Replace('>', '/'); if (!path[path.Length - 1].Equals('/')) { path = path.Insert(path.Length, "/"); } if (redirectPath[redirectPath.Length - 1].Equals('>')) { redirectPath = redirectPath.Substring(0, redirectPath.Length - 1); } } path = $"{env.GetStorageFolderFullPath()}{path}"; if (!Directory.Exists(path) || !HasAccessToFolder(path, env)) { redirectPath = null; return; } FileManagerObjectType?type = null; int pointIndex = fileOrFolderFullName.LastIndexOf('.'); if (pointIndex == -1) { type = FileManagerObjectType.Folder; } else { string fileExtension = fileOrFolderFullName.Substring(pointIndex); foreach (var typeOfExtension in typesOfExtensions) { if (fileExtension.Equals(typeOfExtension.Key)) { type = typeOfExtension.Value; break; } } if (!type.HasValue) { redirectPath = null; return; } for (int i = 0; i < pointIndex; ++i) { bool correctSymbol = false; foreach (var symbol in availableSymbolsInName) { if (fileOrFolderFullName[i].Equals(symbol)) { correctSymbol = true; break; } } if (!correctSymbol) { redirectPath = null; return; } } } if (type != FileManagerObjectType.Folder) { string pathToFile = $"{path}{fileOrFolderFullName}"; if (File.Exists(pathToFile)) { if (type == FileManagerObjectType.Image) { ImagesManagementFunctions.DeleteImage(path, fileOrFolderFullName, db, env); } else { File.Delete(pathToFile); } } else { redirectPath = null; } LogManagementFunctions.AddAdminPanelLog( db: db, context: context, info: $"{pathToFile.Substring(env.GetStorageFolderFullPath().Length - 1)}: {(context.Items["LogLocalization"] as IAdminPanelLogLocalization)?.FileDeleted}" ); } else { string pathToFolder = $"{path}{fileOrFolderFullName}/"; if (!Directory.Exists(pathToFolder)) { redirectPath = null; return; } foreach (var dir in env.GetStorageDirectoriesInfo()) { if (pathToFolder.Equals(dir.Path, StringComparison.OrdinalIgnoreCase)) { redirectPath = null; return; } } Directory.Delete(pathToFolder, true); LogManagementFunctions.AddAdminPanelLog( db: db, context: context, info: $"{pathToFolder.Substring(env.GetStorageFolderFullPath().Length - 1)}: {(context.Items["LogLocalization"] as IAdminPanelLogLocalization)?.FolderDeleted}" ); } }