From b4a756a3eaba58d7d8840e998a09a7e06b2a98ce Mon Sep 17 00:00:00 2001 From: Nguyen Thien Tu <15050790+thientu995@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:55:13 +0700 Subject: [PATCH 1/4] fix warning and info visual studio --- .../CurrentItemExtension.cs | 48 ++++++------------- .../CurrentSiteExtension.cs | 28 +++++------ .../CustomBlockPreviewLocationExpander.cs | 46 ++++++++---------- .../uTPro.Project.Web/Views/uTPro/_Nav.cshtml | 6 ++- 4 files changed, 51 insertions(+), 77 deletions(-) diff --git a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs index 1b0b5f6..a077ca3 100644 --- a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs +++ b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentItemExtension.cs @@ -24,7 +24,10 @@ public interface ICurrentItemExtension IPublishedContent? PageHome { get; } IPublishedContent? PageErrors { get; } } - internal class CurrentItemExtension : ICurrentItemExtension, IDisposable + internal class CurrentItemExtension( + ILogger logger, + ICurrentSiteExtension currentSite + ) : ICurrentItemExtension, IDisposable { ~CurrentItemExtension() { @@ -46,19 +49,8 @@ protected virtual void Dispose(bool disposing) // free native resources if there are any. } - readonly ICurrentSiteExtension _currentSite; - readonly ILogger _logger; - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public CurrentItemExtension( - ILogger logger, - ICurrentSiteExtension currentSite) -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - { - _logger = logger; - _currentSite = currentSite; - - } + readonly ICurrentSiteExtension _currentSite = currentSite; + readonly ILogger _logger = logger; public GlobalRoot Root { @@ -73,10 +65,7 @@ public GlobalFolderSites FolderSite get { var folderSite = this.PageHome?.Parent() ?? null; - if (folderSite == null) - { - folderSite = (GlobalFolderSites)GetItemByAlias(this.PageHome, GlobalFolderSites.ModelTypeAlias, true); - } + folderSite ??= (GlobalFolderSites)GetItemByAlias(this.PageHome, GlobalFolderSites.ModelTypeAlias, true); return folderSite ?? throw new Exception(nameof(GlobalFolderSites) + " is null"); } } @@ -105,19 +94,12 @@ public IPublishedContent? Current { get { - IPublishedContent? currentItem = null; - if (_currentSite.UContext.PublishedRequest?.PublishedContent != null) - { - currentItem = _currentSite.UContext.PublishedRequest?.PublishedContent; - } - else - { - currentItem = this.PageHome; - } - return currentItem; + var published = _currentSite.UContext.PublishedRequest?.PublishedContent; + return published ?? this.PageHome; } } + public IPublishedContent? PageHome { get @@ -181,9 +163,7 @@ public IPublishedContent? PageErrors private IPublishedContent GetItemByAlias(IPublishedContent? item, string alias, bool isFirst) { // Start from provided item - var current = item; - if (current == null) - throw new Exception("Not found item: " + alias); + var current = item ?? throw new Exception("Not found item: " + alias); // quick check if (string.Equals(current.ContentType?.Alias, alias, StringComparison.OrdinalIgnoreCase)) @@ -231,7 +211,7 @@ private static (string, string?) GetIdParent(string pathId, bool isRoot = false) if (pathId.StartsWith("-1", StringComparison.Ordinal)) { int firstComma = pathId.IndexOf(','); - pathIds = (firstComma >= 0 && firstComma + 1 < pathId.Length) ? pathId.Substring(firstComma + 1) : string.Empty; + pathIds = (firstComma >= 0 && firstComma + 1 < pathId.Length) ? pathId[(firstComma + 1)..] : string.Empty; } if (string.IsNullOrEmpty(pathIds)) @@ -240,7 +220,7 @@ private static (string, string?) GetIdParent(string pathId, bool isRoot = false) if (isRoot) { int firstComma = pathIds.IndexOf(','); - var root = firstComma >= 0 ? pathIds.Substring(0, firstComma) : pathIds; + var root = firstComma >= 0 ? pathIds[..firstComma] : pathIds; return (root ?? string.Empty, pathIds); } @@ -257,7 +237,7 @@ private static (string, string?) GetIdParent(string pathId, bool isRoot = false) } else { - parent = pathIds.Substring(0, lastComma); + parent = pathIds[..lastComma]; } return (parent, pathIds); } diff --git a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs index 1aca9b9..17184f2 100644 --- a/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs +++ b/uTPro/Extension/uTPro.Extension.CurrentSite/CurrentSiteExtension.cs @@ -77,10 +77,7 @@ public CultureInfo CurrentCulture { get { - if (this._currentCulture == null) - { - this._currentCulture = Thread.CurrentThread.CurrentCulture; - } + this._currentCulture ??= Thread.CurrentThread.CurrentCulture; return this._currentCulture; } } @@ -129,10 +126,7 @@ public IUmbracoContext UContext { get { - if (this._umbracoContext == null) - { - this._umbracoContext = _umbracoContextFactory.EnsureUmbracoContext().UmbracoContext; - } + this._umbracoContext ??= _umbracoContextFactory.EnsureUmbracoContext().UmbracoContext; return this._umbracoContext ?? throw new Exception("UmbracoContext is null"); } @@ -166,8 +160,8 @@ public string GetDictionaryValue(string key, string valueDefault = "", bool show } // Simple in-memory cache for all domains to reduce repeated UContext access - private static readonly object _domainsLock = new object(); - private static IEnumerable _cachedAllDomains = Enumerable.Empty(); + private static readonly Lock _domainsLock = new(); + private static IEnumerable _cachedAllDomains = []; private static DateTime _cachedAllDomainsExpires = DateTime.MinValue; private const int CachedAllDomainsSeconds = 60; @@ -181,7 +175,7 @@ public Task> GetDomains(bool isGetAll) return Task.FromResult(_cachedAllDomains); } - var all = UContext?.Domains?.GetAll(true) ?? new List(); + var all = UContext?.Domains?.GetAll(true) ?? []; lock (_domainsLock) { _cachedAllDomains = all; @@ -192,7 +186,7 @@ public Task> GetDomains(bool isGetAll) var idItem = this.GetItem().Current?.Id; var domain = UContext?.Domains?.GetAssigned(idItem ?? 0, true); - return Task.FromResult(domain ?? new List()); + return Task.FromResult(domain ?? []); } public void SetCurrentCulture(CultureInfo cul) => this._currentCulture = cul; @@ -205,11 +199,11 @@ public string GetUrlWithCulture(IPublishedContent content, string? culture = nul if (domain != null) { - var domainUrl = domain.Name.StartsWith("/") - || domain.Name.StartsWith("http://", StringComparison.OrdinalIgnoreCase) - || domain.Name.StartsWith("https://", StringComparison.OrdinalIgnoreCase) - ? domain.Name - : "https://" + domain.Name; + var domainUrl = !(domain.Name.StartsWith('/') + || domain.Name.StartsWith("http://", StringComparison.OrdinalIgnoreCase) + || domain.Name.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) + ? "https://" + domain.Name + : domain.Name; var uri = new Uri(domainUrl, UriKind.RelativeOrAbsolute); var segment = uri.AbsolutePath.Trim('/'); diff --git a/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs b/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs index 4fb931b..c0f3b0a 100644 --- a/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs +++ b/uTPro/Project/uTPro.Project.Web.Configure/CustomBlockPreviewLocationExpander.cs @@ -25,29 +25,25 @@ namespace uTPro.Project.Web.Configure { - public class CustomBlockPreviewService : BlockPreviewService + public class CustomBlockPreviewService( + ITempDataProvider tempDataProvider, + IViewComponentHelperWrapper viewComponentHelperWrapper, + IRazorViewEngine razorViewEngine, + ITypeFinder typeFinder, + BlockEditorConverter blockEditorConverter, + IViewComponentSelector viewComponentSelector, + IPublishedValueFallback publishedValueFallback, + IOptions options, + IJsonSerializer jsonSerializer, + IContentTypeService contentTypeService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IWebHostEnvironment webHostEnvironment, + IBlockEditorElementTypeCache elementTypeCache, + ILogger logger) : BlockPreviewService(tempDataProvider, viewComponentHelperWrapper, razorViewEngine, typeFinder, blockEditorConverter, viewComponentSelector, publishedValueFallback, options, jsonSerializer, contentTypeService, dataTypeService, appCaches, webHostEnvironment, elementTypeCache, logger) { - IRazorViewEngine _razorViewEngine; - public CustomBlockPreviewService( - ITempDataProvider tempDataProvider, - IViewComponentHelperWrapper viewComponentHelperWrapper, - IRazorViewEngine razorViewEngine, - ITypeFinder typeFinder, - BlockEditorConverter blockEditorConverter, - IViewComponentSelector viewComponentSelector, - IPublishedValueFallback publishedValueFallback, - IOptions options, - IJsonSerializer jsonSerializer, - IContentTypeService contentTypeService, - IDataTypeService dataTypeService, - AppCaches appCaches, - IWebHostEnvironment webHostEnvironment, - IBlockEditorElementTypeCache elementTypeCache, - ILogger logger) - : base(tempDataProvider, viewComponentHelperWrapper, razorViewEngine, typeFinder, blockEditorConverter, viewComponentSelector, publishedValueFallback, options, jsonSerializer, contentTypeService, dataTypeService, appCaches, webHostEnvironment, elementTypeCache, logger) - { - _razorViewEngine = razorViewEngine; - } + readonly IRazorViewEngine _razorViewEngine = razorViewEngine; + protected override ViewEngineResult? GetViewResult(BlockPreviewContext context) { var blockGrid = CustomPathViews.GetPathViewBlockGridPreview("~/Views/Partials/blockgrid/Components/" + context.ContentAlias, isCheckSiteName: false); @@ -168,7 +164,7 @@ public static class CustomPathViews { // Basic sanitization: remove leading slashes and keep only filename part to avoid traversal fileName = fileName.TrimStart('/', '\\'); - if (fileName.IndexOfAny(new[] { '\\', '/' }) >= 0) + if (fileName.IndexOfAny(['\\', '/']) >= 0) { fileName = Path.GetFileName(fileName); } @@ -217,8 +213,8 @@ public static (string, string) GetSiteAndFileName(string viewName, string siteNa var idx = viewName.IndexOf(prefix, StringComparison.OrdinalIgnoreCase); if (idx > 0) { - var parsedSite = viewName.Substring(0, idx); - var parsedFile = idx + prefix.Length < viewName.Length ? viewName.Substring(idx + prefix.Length) : string.Empty; + var parsedSite = viewName[..idx]; + var parsedFile = idx + prefix.Length < viewName.Length ? viewName[(idx + prefix.Length)..] : string.Empty; if (isCheckSiteName) { diff --git a/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml b/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml index 931351f..8c46374 100644 --- a/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml +++ b/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml @@ -37,7 +37,11 @@ var url = CurrentSite.GetUrlWithCulture(Model, item.Culture, UrlMode.Auto); if (url == "#" || string.IsNullOrEmpty(url)) { - url = CurrentSite.GetUrlWithCulture(CurrentSite.GetItem().PageHome, item.Culture, UrlMode.Auto); + var pageHome = CurrentSite.GetItem().PageHome; + if (pageHome != null) + { + url = CurrentSite.GetUrlWithCulture(pageHome, item.Culture, UrlMode.Auto); + } } if (string.IsNullOrEmpty(url)) continue; From 896a2a14823f30c625d4b2efc0de0d07976ebd5d Mon Sep 17 00:00:00 2001 From: Nguyen Thien Tu <15050790+thientu995@users.noreply.github.com> Date: Thu, 5 Feb 2026 18:06:17 +0700 Subject: [PATCH 2/4] add class language with mobile mode --- uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml b/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml index 8c46374..67c3095 100644 --- a/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml +++ b/uTPro/Project/uTPro.Project.Web/Views/uTPro/_Nav.cshtml @@ -97,7 +97,7 @@ @optionHtml -