performance improvements to reduce http and database interactions
This commit is contained in:
parent
4cae3f02ed
commit
3c6ebd7742
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Linq;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
|
||||||
namespace Oqtane.UI
|
namespace Oqtane.UI
|
||||||
|
@ -8,11 +9,8 @@ namespace Oqtane.UI
|
||||||
{
|
{
|
||||||
public Alias Alias { get; set; }
|
public Alias Alias { get; set; }
|
||||||
public Site Site { get; set; }
|
public Site Site { get; set; }
|
||||||
public List<Language> Languages { get; set; }
|
|
||||||
public List<Page> Pages { get; set; }
|
|
||||||
public Page Page { get; set; }
|
public Page Page { get; set; }
|
||||||
public User User { get; set; }
|
public User User { get; set; }
|
||||||
public List<Module> Modules { get; set; }
|
|
||||||
public Uri Uri { get; set; }
|
public Uri Uri { get; set; }
|
||||||
public Dictionary<string, string> QueryString { get; set; }
|
public Dictionary<string, string> QueryString { get; set; }
|
||||||
public string UrlParameters { get; set; }
|
public string UrlParameters { get; set; }
|
||||||
|
@ -24,5 +22,18 @@ namespace Oqtane.UI
|
||||||
public int VisitorId { get; set; }
|
public int VisitorId { get; set; }
|
||||||
public string RemoteIPAddress { get; set; }
|
public string RemoteIPAddress { get; set; }
|
||||||
public string ReturnUrl { get; set; }
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
public List<Page> Pages
|
||||||
|
{
|
||||||
|
get { return Site.Pages; }
|
||||||
|
}
|
||||||
|
public List<Module> Modules
|
||||||
|
{
|
||||||
|
get { return Site.Modules; }
|
||||||
|
}
|
||||||
|
public List<Language> Languages
|
||||||
|
{
|
||||||
|
get { return Site.Languages; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,8 @@
|
||||||
@inject INavigationInterception NavigationInterception
|
@inject INavigationInterception NavigationInterception
|
||||||
@inject ISyncService SyncService
|
@inject ISyncService SyncService
|
||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
@inject ILanguageService LanguageService
|
|
||||||
@inject IPageService PageService
|
@inject IPageService PageService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IModuleService ModuleService
|
|
||||||
@inject IUrlMappingService UrlMappingService
|
@inject IUrlMappingService UrlMappingService
|
||||||
@inject ILogService LogService
|
@inject ILogService LogService
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
@ -181,14 +179,13 @@
|
||||||
|
|
||||||
if (PageState == null || refresh == UI.Refresh.Site)
|
if (PageState == null || refresh == UI.Refresh.Site)
|
||||||
{
|
{
|
||||||
languages = await LanguageService.GetLanguagesAsync(site.SiteId);
|
pages = site.Pages.Where(item => !item.IsDeleted).ToList();
|
||||||
pages = await PageService.GetPagesAsync(site.SiteId);
|
languages = site.Languages;
|
||||||
pages = pages.Where(item => !item.IsDeleted).ToList();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
languages = PageState.Languages;
|
|
||||||
pages = PageState.Pages;
|
pages = PageState.Pages;
|
||||||
|
languages = PageState.Languages;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PageState == null || refresh == UI.Refresh.Site)
|
if (PageState == null || refresh == UI.Refresh.Site)
|
||||||
|
@ -226,8 +223,7 @@
|
||||||
|
|
||||||
if (PageState == null || refresh == UI.Refresh.Site)
|
if (PageState == null || refresh == UI.Refresh.Site)
|
||||||
{
|
{
|
||||||
modules = await ModuleService.GetModulesAsync(site.SiteId);
|
modules = site.Modules.Where(item => !item.IsDeleted).ToList();
|
||||||
modules = modules.Where(item => !item.IsDeleted).ToList();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -240,11 +236,8 @@
|
||||||
{
|
{
|
||||||
Alias = SiteState.Alias,
|
Alias = SiteState.Alias,
|
||||||
Site = site,
|
Site = site,
|
||||||
Languages = languages,
|
|
||||||
Pages = pages,
|
|
||||||
Page = page,
|
Page = page,
|
||||||
User = user,
|
User = user,
|
||||||
Modules = modules,
|
|
||||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||||
QueryString = querystring,
|
QueryString = querystring,
|
||||||
UrlParameters = route.UrlParameters,
|
UrlParameters = route.UrlParameters,
|
||||||
|
|
|
@ -24,9 +24,9 @@ namespace Oqtane.Controllers
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
private readonly Alias _alias;
|
private readonly Alias _alias;
|
||||||
|
|
||||||
public LanguageController(ILanguageRepository language, ISyncManager syncManager, ILogManager logger, ITenantManager tenantManager)
|
public LanguageController(ILanguageRepository languages, ISyncManager syncManager, ILogManager logger, ITenantManager tenantManager)
|
||||||
{
|
{
|
||||||
_languages = language;
|
_languages = languages;
|
||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_alias = tenantManager.GetAlias();
|
_alias = tenantManager.GetAlias();
|
||||||
|
|
|
@ -8,6 +8,11 @@ using Oqtane.Enums;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using Oqtane.Security;
|
||||||
|
using System.Globalization;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Oqtane.Extensions;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
|
@ -15,17 +20,31 @@ namespace Oqtane.Controllers
|
||||||
public class SiteController : Controller
|
public class SiteController : Controller
|
||||||
{
|
{
|
||||||
private readonly ISiteRepository _sites;
|
private readonly ISiteRepository _sites;
|
||||||
|
private readonly IPageRepository _pages;
|
||||||
|
private readonly IModuleRepository _modules;
|
||||||
|
private readonly IPageModuleRepository _pageModules;
|
||||||
|
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
||||||
|
private readonly ILanguageRepository _languages;
|
||||||
|
private readonly IUserPermissions _userPermissions;
|
||||||
private readonly ISettingRepository _settings;
|
private readonly ISettingRepository _settings;
|
||||||
private readonly ISyncManager _syncManager;
|
private readonly ISyncManager _syncManager;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
private readonly Alias _alias;
|
private readonly Alias _alias;
|
||||||
|
|
||||||
public SiteController(ISiteRepository sites, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
public SiteController(ISiteRepository sites, IPageRepository pages, IModuleRepository modules, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache)
|
||||||
{
|
{
|
||||||
_sites = sites;
|
_sites = sites;
|
||||||
|
_pages = pages;
|
||||||
|
_modules = modules;
|
||||||
|
_pageModules = pageModules;
|
||||||
|
_moduleDefinitions = moduleDefinitions;
|
||||||
|
_languages = languages;
|
||||||
|
_userPermissions = userPermissions;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_cache = cache;
|
||||||
_alias = tenantManager.GetAlias();
|
_alias = tenantManager.GetAlias();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,17 +60,92 @@ namespace Oqtane.Controllers
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public Site Get(int id)
|
public Site Get(int id)
|
||||||
{
|
{
|
||||||
var site = _sites.GetSite(id);
|
if (!User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
return _cache.GetOrCreate($"site:{HttpContext.GetAlias().SiteKey}", entry =>
|
||||||
|
{
|
||||||
|
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||||
|
return GetSite(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GetSite(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Site GetSite(int siteid)
|
||||||
|
{
|
||||||
|
var site = _sites.GetSite(siteid);
|
||||||
if (site.SiteId == _alias.SiteId)
|
if (site.SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
|
// site settings
|
||||||
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
||||||
.Where(item => !item.IsPrivate || User.IsInRole(RoleNames.Admin))
|
.Where(item => !item.IsPrivate || User.IsInRole(RoleNames.Admin))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
|
||||||
|
// pages
|
||||||
|
List<Setting> settings = _settings.GetSettings(EntityNames.Page).ToList();
|
||||||
|
site.Pages = new List<Page>();
|
||||||
|
foreach (Page page in _pages.GetPages(site.SiteId))
|
||||||
|
{
|
||||||
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
||||||
|
{
|
||||||
|
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
||||||
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
site.Pages.Add(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// modules
|
||||||
|
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(site.SiteId).ToList();
|
||||||
|
settings = _settings.GetSettings(EntityNames.Module).ToList();
|
||||||
|
site.Modules = new List<Module>();
|
||||||
|
foreach (PageModule pagemodule in _pageModules.GetPageModules(site.SiteId))
|
||||||
|
{
|
||||||
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.Permissions))
|
||||||
|
{
|
||||||
|
Module module = new Module();
|
||||||
|
module.SiteId = pagemodule.Module.SiteId;
|
||||||
|
module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName;
|
||||||
|
module.AllPages = pagemodule.Module.AllPages;
|
||||||
|
module.Permissions = pagemodule.Module.Permissions;
|
||||||
|
module.CreatedBy = pagemodule.Module.CreatedBy;
|
||||||
|
module.CreatedOn = pagemodule.Module.CreatedOn;
|
||||||
|
module.ModifiedBy = pagemodule.Module.ModifiedBy;
|
||||||
|
module.ModifiedOn = pagemodule.Module.ModifiedOn;
|
||||||
|
module.DeletedBy = pagemodule.DeletedBy;
|
||||||
|
module.DeletedOn = pagemodule.DeletedOn;
|
||||||
|
module.IsDeleted = pagemodule.IsDeleted;
|
||||||
|
|
||||||
|
module.PageModuleId = pagemodule.PageModuleId;
|
||||||
|
module.ModuleId = pagemodule.ModuleId;
|
||||||
|
module.PageId = pagemodule.PageId;
|
||||||
|
module.Title = pagemodule.Title;
|
||||||
|
module.Pane = pagemodule.Pane;
|
||||||
|
module.Order = pagemodule.Order;
|
||||||
|
module.ContainerType = pagemodule.ContainerType;
|
||||||
|
|
||||||
|
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||||
|
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.Permissions))
|
||||||
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
|
||||||
|
site.Modules.Add(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// languages
|
||||||
|
site.Languages = _languages.GetLanguages(site.SiteId).ToList();
|
||||||
|
var defaultCulture = CultureInfo.GetCultureInfo(Constants.DefaultCulture);
|
||||||
|
site.Languages.Add(new Language { Code = defaultCulture.Name, Name = defaultCulture.DisplayName, Version = Constants.Version, IsDefault = !site.Languages.Any(l => l.IsDefault) });
|
||||||
|
|
||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Get Attempt {SiteId}", id);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Get Attempt {SiteId}", siteid);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using Oqtane.Shared;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Oqtane.Repository;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Oqtane.Infrastructure
|
namespace Oqtane.Infrastructure
|
||||||
{
|
{
|
||||||
public class SyncManager : ISyncManager
|
public class SyncManager : ISyncManager
|
||||||
{
|
{
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
private List<SyncEvent> SyncEvents { get; set; }
|
private List<SyncEvent> SyncEvents { get; set; }
|
||||||
|
|
||||||
public SyncManager()
|
public SyncManager(IMemoryCache cache)
|
||||||
{
|
{
|
||||||
|
_cache = cache;
|
||||||
SyncEvents = new List<SyncEvent>();
|
SyncEvents = new List<SyncEvent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +32,10 @@ namespace Oqtane.Infrastructure
|
||||||
public void AddSyncEvent(int tenantId, string entityName, int entityId, bool reload)
|
public void AddSyncEvent(int tenantId, string entityName, int entityId, bool reload)
|
||||||
{
|
{
|
||||||
SyncEvents.Add(new SyncEvent { TenantId = tenantId, EntityName = entityName, EntityId = entityId, Reload = reload, ModifiedOn = DateTime.UtcNow });
|
SyncEvents.Add(new SyncEvent { TenantId = tenantId, EntityName = entityName, EntityId = entityId, Reload = reload, ModifiedOn = DateTime.UtcNow });
|
||||||
|
if (entityName == EntityNames.Site)
|
||||||
|
{
|
||||||
|
_cache.Remove($"site:{tenantId}:{entityId}");
|
||||||
|
}
|
||||||
// trim sync events
|
// trim sync events
|
||||||
SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.UtcNow.AddHours(-1));
|
SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.UtcNow.AddHours(-1));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Oqtane.Infrastructure;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Oqtane.Modules.HtmlText.Repository
|
namespace Oqtane.Modules.HtmlText.Repository
|
||||||
{
|
{
|
||||||
|
@ -8,15 +11,23 @@ namespace Oqtane.Modules.HtmlText.Repository
|
||||||
public class HtmlTextRepository : IHtmlTextRepository, ITransientService
|
public class HtmlTextRepository : IHtmlTextRepository, ITransientService
|
||||||
{
|
{
|
||||||
private readonly HtmlTextContext _db;
|
private readonly HtmlTextContext _db;
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
|
private readonly SiteState _siteState;
|
||||||
|
|
||||||
public HtmlTextRepository(HtmlTextContext context)
|
public HtmlTextRepository(HtmlTextContext context, IMemoryCache cache, SiteState siteState)
|
||||||
{
|
{
|
||||||
_db = context;
|
_db = context;
|
||||||
|
_cache = cache;
|
||||||
|
_siteState = siteState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Models.HtmlText> GetHtmlTexts(int moduleId)
|
public IEnumerable<Models.HtmlText> GetHtmlTexts(int moduleId)
|
||||||
{
|
{
|
||||||
return _db.HtmlText.Where(item => item.ModuleId == moduleId);
|
return _cache.GetOrCreate($"HtmlText:{_siteState.Alias.SiteKey}:{moduleId}", entry =>
|
||||||
|
{
|
||||||
|
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||||
|
return _db.HtmlText.Where(item => item.ModuleId == moduleId).ToList();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Models.HtmlText GetHtmlText(int htmlTextId)
|
public Models.HtmlText GetHtmlText(int htmlTextId)
|
||||||
|
@ -28,6 +39,7 @@ namespace Oqtane.Modules.HtmlText.Repository
|
||||||
{
|
{
|
||||||
_db.HtmlText.Add(htmlText);
|
_db.HtmlText.Add(htmlText);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
ClearCache(htmlText.ModuleId);
|
||||||
return htmlText;
|
return htmlText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +47,13 @@ namespace Oqtane.Modules.HtmlText.Repository
|
||||||
{
|
{
|
||||||
Models.HtmlText htmlText = _db.HtmlText.FirstOrDefault(item => item.HtmlTextId == htmlTextId);
|
Models.HtmlText htmlText = _db.HtmlText.FirstOrDefault(item => item.HtmlTextId == htmlTextId);
|
||||||
if (htmlText != null) _db.HtmlText.Remove(htmlText);
|
if (htmlText != null) _db.HtmlText.Remove(htmlText);
|
||||||
|
ClearCache(htmlText.ModuleId);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ClearCache(int moduleId)
|
||||||
|
{
|
||||||
|
_cache.Remove($"HtmlText:{_siteState.Alias.SiteKey}:{moduleId}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Oqtane.Extensions;
|
using Oqtane.Extensions;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
|
|
@ -109,7 +109,6 @@ namespace Oqtane.Models
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IModuleControl properties
|
#region IModuleControl properties
|
||||||
// TODO: unclear why these are IModuleControl properties - there is no such interface
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public SecurityAccessLevel SecurityAccessLevel { get; set; }
|
public SecurityAccessLevel SecurityAccessLevel { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
|
|
|
@ -83,6 +83,18 @@ namespace Oqtane.Models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public Dictionary<string, string> Settings { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public List<Page> Pages { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public List<Module> Modules { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public List<Language> Languages { get; set; }
|
||||||
|
|
||||||
#region IAuditable Properties
|
#region IAuditable Properties
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@ -101,17 +113,16 @@ namespace Oqtane.Models
|
||||||
public string DeletedBy { get; set; }
|
public string DeletedBy { get; set; }
|
||||||
public DateTime? DeletedOn { get; set; }
|
public DateTime? DeletedOn { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public string SiteTemplateType { get; set; }
|
public string SiteTemplateType { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
#region Obsolete properties
|
||||||
public Dictionary<string, string> Settings { get; set; }
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[Obsolete("This property is deprecated.", false)]
|
[Obsolete("This property is deprecated.", false)]
|
||||||
public string DefaultLayoutType { get; set; }
|
public string DefaultLayoutType { get; set; }
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user