Added ability for Runtime and RenderMode to be set per Site - enabling the framework to support multiple hosting models concurrently in the same installation. Fixed WebAssembly Prerendering issue (this also resolved the issue where the component taghelper was not passing parameters correctly to the app when running on WebAssembly). Fix #1702 - remove web,config from upgrade package.

This commit is contained in:
Shaun Walker 2021-10-05 14:32:05 -04:00
parent ac67d88e74
commit 306b78b526
23 changed files with 190 additions and 90 deletions

View File

@ -62,21 +62,10 @@
_initialized = true; _initialized = true;
} }
protected override async Task OnAfterRenderAsync(bool firstRender) protected override void OnAfterRender(bool firstRender)
{ {
if (firstRender) if (firstRender)
{ {
if (string.IsNullOrEmpty(AntiForgeryToken))
{
// parameter values are not set when running on WebAssembly (seems to be a .NET 5 bug) - need to retrieve using JSInterop
var interop = new Interop(JSRuntime);
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
InstallationService.SetAntiForgeryTokenHeader(SiteState.AntiForgeryToken);
Runtime = await interop.GetElementByName("app_runtime");
RenderMode = await interop.GetElementByName("app_rendermode");
}
_display = ""; _display = "";
StateHasChanged(); StateHasChanged();
} }

View File

@ -104,7 +104,6 @@
</select> </select>
</div> </div>
</div> </div>
</div> </div>
</Section> </Section>
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings"> <Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
@ -157,10 +156,7 @@
</div> </div>
<button type="button" class="btn btn-secondary" @onclick="SendEmail">@Localizer["Smtp.TestConfig"]</button> <button type="button" class="btn btn-secondary" @onclick="SendEmail">@Localizer["Smtp.TestConfig"]</button>
<br /><br /> <br /><br />
</div> </div>
</Section> </Section>
<Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings"> <Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings">
<div class="container"> <div class="container">
@ -189,6 +185,28 @@
</Section> </Section>
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
<Section Name="Hosting" Heading="Hosting Model" ResourceKey="Hosting">
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="runtime" HelpText="The Blazor runtime hosting model" ResourceKey="Runtime">Runtime: </Label>
<div class="col-sm-9">
<select id="runtime" class="form-select" @bind="@_runtime" required>
<option value="Server">@SharedLocalizer["BlazorServer"]</option>
<option value="WebAssembly">@SharedLocalizer["BlazorWebAssembly"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="prerender" HelpText="Specifies if the site should be prerendered (for search crawlers, etc...)" ResourceKey="Prerender">Prerender? </Label>
<div class="col-sm-9">
<select id="prerender" class="form-select" @bind="@_prerender" required>
<option value="Prerendered">@SharedLocalizer["Yes"]</option>
<option value="">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
</div>
</Section>
<Section Name="TenantInformation" Heading="Tenant Information" ResourceKey="TenantInformation"> <Section Name="TenantInformation" Heading="Tenant Information" ResourceKey="TenantInformation">
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
@ -231,6 +249,8 @@
private string _name = string.Empty; private string _name = string.Empty;
private List<Alias> _aliasList; private List<Alias> _aliasList;
private string _urls = string.Empty; private string _urls = string.Empty;
private string _runtime = "";
private string _prerender = "";
private int _logofileid = -1; private int _logofileid = -1;
private FileManager _logofilemanager; private FileManager _logofilemanager;
private int _faviconfileid = -1; private int _faviconfileid = -1;
@ -272,6 +292,8 @@
if (site != null) if (site != null)
{ {
_name = site.Name; _name = site.Name;
_runtime = site.Runtime;
_prerender = site.RenderMode.Replace(_runtime, "");
_allowregistration = site.AllowRegistration.ToString(); _allowregistration = site.AllowRegistration.ToString();
_isdeleted = site.IsDeleted.ToString(); _isdeleted = site.IsDeleted.ToString();
@ -413,9 +435,20 @@
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId); var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null) if (site != null)
{ {
bool reload = false;
bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype); bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype);
site.Name = _name; site.Name = _name;
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
{
site.Runtime = _runtime;
site.RenderMode = _runtime + _prerender;
refresh = true;
reload = true;
}
}
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration)); site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
@ -485,7 +518,7 @@
if (refresh) if (refresh)
{ {
NavigationManager.NavigateTo(NavigateUrl()); // refresh to show new theme or container NavigationManager.NavigateTo(NavigateUrl(), reload); // refresh to show new theme or container
} }
else else
{ {

View File

@ -82,6 +82,24 @@ else
</select> </select>
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="runtime" HelpText="The runtime hosting model" ResourceKey="Runtime">Runtime: </Label>
<div class="col-sm-9">
<select id="runtime" class="form-select" @bind="@_runtime" required>
<option value="Server">@SharedLocalizer["BlazorServer"]</option>
<option value="WebAssembly">@SharedLocalizer["BlazorWebAssembly"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="prerender" HelpText="Specifies if the site should be prerendered (for search crawlers, etc...)" ResourceKey="Prerender">Prerender? </Label>
<div class="col-sm-9">
<select id="prerender" class="form-select" @bind="@_prerender" required>
<option value="Prerendered">@SharedLocalizer["Yes"]</option>
<option value="">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="tenant" HelpText="Select the tenant for the site" ResourceKey="Tenant">Tenant: </Label> <Label Class="col-sm-3" For="tenant" HelpText="Select the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
@ -177,6 +195,8 @@ else
private string _containertype = "-"; private string _containertype = "-";
private string _admincontainertype = ""; private string _admincontainertype = "";
private string _sitetemplatetype = "-"; private string _sitetemplatetype = "-";
private string _runtime = "Server";
private string _prerender = "Prerendered";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -340,6 +360,8 @@ else
config.DefaultContainer = _containertype; config.DefaultContainer = _containertype;
config.DefaultAdminContainer = _admincontainertype; config.DefaultAdminContainer = _admincontainertype;
config.SiteTemplate = _sitetemplatetype; config.SiteTemplate = _sitetemplatetype;
config.Runtime = _runtime;
config.RenderMode = _runtime + _prerender;
ShowProgressIndicator(); ShowProgressIndicator();

View File

@ -50,24 +50,6 @@
</TabPanel> </TabPanel>
<TabPanel Name="Options" Heading="Options" ResourceKey="Options"> <TabPanel Name="Options" Heading="Options" ResourceKey="Options">
<div class="container"> <div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="runtime" HelpText="Blazor Runtime (Server or WebAssembly)" ResourceKey="BlazorRuntime">Blazor Runtime: </Label>
<div class="col-sm-9">
<select id="runtime" class="form-select" @bind="@_runtime">
<option value="Server">@Localizer["Server"]</option>
<option value="WebAssembly">@Localizer["WebAssembly"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="rendermode" HelpText="Blazor Server Render Mode" ResourceKey="RenderMode">Render Mode: </Label>
<div class="col-sm-9">
<select id="rendermode" class="form-select" @bind="@_rendermode">
<option value="Server">@Localizer["Server"]</option>
<option value="ServerPrerendered">@Localizer["ServerPrerendered"]</option>
</select>
</div>
</div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="detailederrors" HelpText="Specify If Detailed Errors Are Enabled For Blazor. This Option Should Not Not Be Enabled In Production." ResourceKey="DetailedErrors">Detailed Errors? </Label> <Label Class="col-sm-3" For="detailederrors" HelpText="Specify If Detailed Errors Are Enabled For Blazor. This Option Should Not Not Be Enabled In Production." ResourceKey="DetailedErrors">Detailed Errors? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
@ -126,8 +108,6 @@
private string _servertime = string.Empty; private string _servertime = string.Empty;
private string _installationid = string.Empty; private string _installationid = string.Empty;
private string _runtime = string.Empty;
private string _rendermode = string.Empty;
private string _detailederrors = string.Empty; private string _detailederrors = string.Empty;
private string _logginglevel = string.Empty; private string _logginglevel = string.Empty;
private string _swagger = string.Empty; private string _swagger = string.Empty;
@ -146,8 +126,6 @@
_servertime = systeminfo["servertime"]; _servertime = systeminfo["servertime"];
_installationid = systeminfo["installationid"]; _installationid = systeminfo["installationid"];
_runtime = systeminfo["runtime"];
_rendermode = systeminfo["rendermode"];
_detailederrors = systeminfo["detailederrors"]; _detailederrors = systeminfo["detailederrors"];
_logginglevel = systeminfo["logginglevel"]; _logginglevel = systeminfo["logginglevel"];
_swagger = systeminfo["swagger"]; _swagger = systeminfo["swagger"];
@ -160,8 +138,6 @@
try try
{ {
var settings = new Dictionary<string, string>(); var settings = new Dictionary<string, string>();
settings.Add("runtime", _runtime);
settings.Add("rendermode", _rendermode);
settings.Add("detailederrors", _detailederrors); settings.Add("detailederrors", _detailederrors);
settings.Add("logginglevel", _logginglevel); settings.Add("logginglevel", _logginglevel);
settings.Add("swagger", _swagger); settings.Add("swagger", _swagger);

View File

@ -24,7 +24,6 @@ namespace Oqtane.Client
public static async Task Main(string[] args) public static async Task Main(string[] args)
{ {
var builder = WebAssemblyHostBuilder.CreateDefault(args); var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
var httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)}; var httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)};

View File

@ -282,4 +282,19 @@
<data name="Theme.Select" xml:space="preserve"> <data name="Theme.Select" xml:space="preserve">
<value>Select Theme</value> <value>Select Theme</value>
</data> </data>
<data name="Hosting" xml:space="preserve">
<value>Hosting Model</value>
</data>
<data name="Prerender.HelpText" xml:space="preserve">
<value>Specifies if the site should be prerendered (for search crawlers, etc...)</value>
</data>
<data name="Prerender.Text" xml:space="preserve">
<value>Prerender? </value>
</data>
<data name="Runtime.HelpText" xml:space="preserve">
<value>The Blazor runtime hosting model</value>
</data>
<data name="Runtime.Text" xml:space="preserve">
<value>Runtime: </value>
</data>
</root> </root>

View File

@ -258,4 +258,16 @@
<data name="Error.Database.LoadConfig" xml:space="preserve"> <data name="Error.Database.LoadConfig" xml:space="preserve">
<value>Error loading Database Configuration Control</value> <value>Error loading Database Configuration Control</value>
</data> </data>
<data name="Prerender.HelpText" xml:space="preserve">
<value>Specifies if the site should be prerendered (for search crawlers, etc...)</value>
</data>
<data name="Prerender.Text" xml:space="preserve">
<value>Prerender? </value>
</data>
<data name="Runtime.HelpText" xml:space="preserve">
<value>The Blazor runtime hosting model</value>
</data>
<data name="Runtime.Text" xml:space="preserve">
<value>Runtime: </value>
</data>
</root> </root>

View File

@ -123,9 +123,6 @@
<data name="FrameworkVersion.HelpText" xml:space="preserve"> <data name="FrameworkVersion.HelpText" xml:space="preserve">
<value>Framework Version</value> <value>Framework Version</value>
</data> </data>
<data name="BlazorRuntime.HelpText" xml:space="preserve">
<value>Blazor Runtime (Server or WebAssembly)</value>
</data>
<data name="CLRVersion.HelpText" xml:space="preserve"> <data name="CLRVersion.HelpText" xml:space="preserve">
<value>Common Language Runtime Version</value> <value>Common Language Runtime Version</value>
</data> </data>
@ -141,9 +138,6 @@
<data name="FrameworkVersion.Text" xml:space="preserve"> <data name="FrameworkVersion.Text" xml:space="preserve">
<value>Framework Version: </value> <value>Framework Version: </value>
</data> </data>
<data name="BlazorRuntime.Text" xml:space="preserve">
<value>Blazor Runtime: </value>
</data>
<data name="CLRVersion.Text" xml:space="preserve"> <data name="CLRVersion.Text" xml:space="preserve">
<value>CLR Version: </value> <value>CLR Version: </value>
</data> </data>
@ -165,18 +159,9 @@
<data name="Error.UpdateConfig" xml:space="preserve"> <data name="Error.UpdateConfig" xml:space="preserve">
<value>An Error Occurred Updating The Configuration</value> <value>An Error Occurred Updating The Configuration</value>
</data> </data>
<data name="Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="ServerPrerendered" xml:space="preserve">
<value>ServerPrerendered</value>
</data>
<data name="Success.UpdateConfig.Restart" xml:space="preserve"> <data name="Success.UpdateConfig.Restart" xml:space="preserve">
<value>Configuration Updated. Please Select Restart Application For These Changes To Be Activated.</value> <value>Configuration Updated. Please Select Restart Application For These Changes To Be Activated.</value>
</data> </data>
<data name="WebAssembly" xml:space="preserve">
<value>WebAssembly</value>
</data>
<data name="InstallationId.Text" xml:space="preserve"> <data name="InstallationId.Text" xml:space="preserve">
<value>Installation ID: </value> <value>Installation ID: </value>
</data> </data>

View File

@ -312,4 +312,10 @@
<data name="Not Specified" xml:space="preserve"> <data name="Not Specified" xml:space="preserve">
<value>Not Specified</value> <value>Not Specified</value>
</data> </data>
<data name="BlazorServer" xml:space="preserve">
<value>Blazor Server</value>
</data>
<data name="BlazorWebAssembly" xml:space="preserve">
<value>Blazor WebAssembly</value>
</data>
</root> </root>

View File

@ -85,19 +85,19 @@
// parse querystring // parse querystring
var querystring = ParseQueryString(uri.Query); var querystring = ParseQueryString(uri.Query);
// reload the client application if there is a forced reload or the user navigated to a site with a different alias
if (querystring.ContainsKey("reload") || (!path.ToLower().StartsWith(SiteState.Alias.Path.ToLower()) && !string.IsNullOrEmpty(SiteState.Alias.Path)))
{
NavigationManager.NavigateTo(_absoluteUri.Replace("?reload", ""), true);
return;
}
else
{
// the refresh parameter is used to refresh the PageState // the refresh parameter is used to refresh the PageState
if (querystring.ContainsKey("refresh")) if (querystring.ContainsKey("refresh"))
{ {
refresh = UI.Refresh.Site; refresh = UI.Refresh.Site;
} }
else
{
// reload the client application if the user navigated to a site with a different alias or there is a forced reload
if ((!path.ToLower().StartsWith(SiteState.Alias.Path.ToLower()) && !string.IsNullOrEmpty(SiteState.Alias.Path)) || querystring.ContainsKey("reload"))
{
NavigationManager.NavigateTo(_absoluteUri.Replace("?reload", ""), true);
return;
}
} }
if (PageState != null) if (PageState != null)
@ -109,10 +109,10 @@
// process any sync events // process any sync events
var sync = await SyncService.GetSyncAsync(lastsyncdate); var sync = await SyncService.GetSyncAsync(lastsyncdate);
lastsyncdate = sync.SyncDate; lastsyncdate = sync.SyncDate;
if (refresh != UI.Refresh.Site && sync.SyncEvents.Any()) if (sync.SyncEvents.Any())
{ {
// if running on WebAssembly reload the client application if the server application was restarted // reload client application if server was restarted or site runtime/rendermode was modified
if (runtime == Shared.Runtime.WebAssembly && PageState != null && sync.SyncEvents.Exists(item => item.TenantId == -1)) if (PageState != null && sync.SyncEvents.Exists(item => (item.TenantId == -1 || item.EntityName == EntityNames.Site && item.EntityId == SiteState.Alias.SiteId) && item.Reload))
{ {
NavigationManager.NavigateTo(_absoluteUri, true); NavigationManager.NavigateTo(_absoluteUri, true);
return; return;

View File

@ -17,6 +17,7 @@ del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json"
ren "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.release.json" "appsettings.json" ren "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.release.json" "appsettings.json"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json" del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json"
del "..\Oqtane.Server\bin\Release\net5.0\publish\web.config"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
dotnet clean -c Release ..\Oqtane.Updater.sln dotnet clean -c Release ..\Oqtane.Updater.sln
dotnet build -c Release ..\Oqtane.Updater.sln dotnet build -c Release ..\Oqtane.Updater.sln

View File

@ -101,17 +101,9 @@ namespace Oqtane.Controllers
// GET api/<controller>/load // GET api/<controller>/load
[HttpGet("load")] [HttpGet("load")]
public IActionResult Load() public IActionResult Load()
{
if (_configManager.GetSection("Runtime").Value == "WebAssembly")
{ {
return File(GetAssemblies(), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.dll"); return File(GetAssemblies(), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.dll");
} }
else
{
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return null;
}
}
private byte[] GetAssemblies() private byte[] GetAssemblies()
{ {

View File

@ -84,10 +84,16 @@ namespace Oqtane.Controllers
[Authorize(Roles = RoleNames.Admin)] [Authorize(Roles = RoleNames.Admin)]
public Site Put(int id, [FromBody] Site site) public Site Put(int id, [FromBody] Site site)
{ {
if (ModelState.IsValid && site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && _sites.GetSite(site.SiteId, false) != null) var current = _sites.GetSite(site.SiteId, false);
if (ModelState.IsValid && site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && current != null)
{ {
site = _sites.UpdateSite(site); site = _sites.UpdateSite(site);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId); bool reload = false;
if (current.Runtime != site.Runtime || current.RenderMode != site.RenderMode)
{
reload = true;
}
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, reload);
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site); _logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site);
} }
else else

View File

@ -585,7 +585,9 @@ namespace Oqtane.Infrastructure
DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme, DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer, DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer, AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
SiteTemplateType = install.SiteTemplate SiteTemplateType = install.SiteTemplate,
Runtime = (!string.IsNullOrEmpty(install.Runtime)) ? install.Runtime : _configManager.GetSection("Runtime").Value,
RenderMode = (!string.IsNullOrEmpty(install.RenderMode)) ? install.RenderMode : _configManager.GetSection("RenderMode").Value
}; };
site = sites.AddSite(site); site = sites.AddSite(site);

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Oqtane.Models; using Oqtane.Models;
@ -8,5 +8,6 @@ namespace Oqtane.Infrastructure
{ {
List<SyncEvent> GetSyncEvents(int tenantId, DateTime lastSyncDate); List<SyncEvent> GetSyncEvents(int tenantId, DateTime lastSyncDate);
void AddSyncEvent(int tenantId, string entityName, int entityId); void AddSyncEvent(int tenantId, string entityName, int entityId);
void AddSyncEvent(int tenantId, string entityName, int entityId, bool reload);
} }
} }

View File

@ -22,7 +22,12 @@ namespace Oqtane.Infrastructure
public void AddSyncEvent(int tenantId, string entityName, int entityId) public void AddSyncEvent(int tenantId, string entityName, int entityId)
{ {
SyncEvents.Add(new SyncEvent { TenantId = tenantId, EntityName = entityName, EntityId = entityId, ModifiedOn = DateTime.UtcNow }); AddSyncEvent(tenantId, entityName, entityId, false);
}
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 });
// trim sync events // trim sync events
SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.UtcNow.AddHours(-1)); SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.UtcNow.AddHours(-1));
} }

View File

@ -1,8 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces; using Oqtane.Databases.Interfaces;
using Oqtane.Interfaces;
namespace Oqtane.Migrations namespace Oqtane.Migrations
{ {

View File

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
namespace Oqtane.Migrations.Tenant
{
[DbContext(typeof(TenantDBContext))]
[Migration("Tenant.03.00.00.01")]
public class AddSiteRuntime : MultiDatabaseMigration
{
public AddSiteRuntime(IDatabase database) : base(database)
{
}
protected override void Up(MigrationBuilder migrationBuilder)
{
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.AddStringColumn("Runtime", 50, true, true);
siteEntityBuilder.UpdateColumn("Runtime", "'Server'");
siteEntityBuilder.AddStringColumn("RenderMode", 50, true, true);
siteEntityBuilder.UpdateColumn("RenderMode", "'ServerPrerendered'");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.DropColumn("Runtime");
siteEntityBuilder.DropColumn("RenderMode");
}
}
}

View File

@ -23,14 +23,16 @@ namespace Oqtane.Pages
private readonly ILocalizationManager _localizationManager; private readonly ILocalizationManager _localizationManager;
private readonly ILanguageRepository _languages; private readonly ILanguageRepository _languages;
private readonly IAntiforgery _antiforgery; private readonly IAntiforgery _antiforgery;
private readonly ISiteRepository _sites;
public HostModel(IConfiguration configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery) public HostModel(IConfiguration configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, ISiteRepository sites)
{ {
_configuration = configuration; _configuration = configuration;
_tenantManager = tenantManager; _tenantManager = tenantManager;
_localizationManager = localizationManager; _localizationManager = localizationManager;
_languages = languages; _languages = languages;
_antiforgery = antiforgery; _antiforgery = antiforgery;
_sites = sites;
} }
public string AntiForgeryToken = ""; public string AntiForgeryToken = "";
@ -48,7 +50,7 @@ namespace Oqtane.Pages
Runtime = _configuration.GetSection("Runtime").Value; Runtime = _configuration.GetSection("Runtime").Value;
} }
if (Runtime != "WebAssembly" && _configuration.GetSection("RenderMode").Exists()) if (_configuration.GetSection("RenderMode").Exists())
{ {
RenderMode = (RenderMode)Enum.Parse(typeof(RenderMode), _configuration.GetSection("RenderMode").Value, true); RenderMode = (RenderMode)Enum.Parse(typeof(RenderMode), _configuration.GetSection("RenderMode").Value, true);
} }
@ -67,6 +69,19 @@ namespace Oqtane.Pages
var alias = _tenantManager.GetAlias(); var alias = _tenantManager.GetAlias();
if (alias != null) if (alias != null)
{ {
var site = _sites.GetSite(alias.SiteId);
if (site != null)
{
if (!string.IsNullOrEmpty(site.Runtime))
{
Runtime = site.Runtime;
}
if (!string.IsNullOrEmpty(site.RenderMode))
{
RenderMode = (RenderMode)Enum.Parse(typeof(RenderMode), site.RenderMode, true);
}
}
// if culture not specified // if culture not specified
if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null) if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null)
{ {
@ -142,7 +157,6 @@ namespace Oqtane.Pages
} }
} }
} }
private void ProcessResource(Resource resource) private void ProcessResource(Resource resource)
{ {
switch (resource.ResourceType) switch (resource.ResourceType)
@ -171,7 +185,6 @@ namespace Oqtane.Pages
break; break;
} }
} }
private string CrossOrigin(string crossorigin) private string CrossOrigin(string crossorigin)
{ {
if (!string.IsNullOrEmpty(crossorigin)) if (!string.IsNullOrEmpty(crossorigin))

View File

@ -163,8 +163,8 @@ namespace Oqtane
endpoints.MapFallbackToPage("/_Host"); endpoints.MapFallbackToPage("/_Host");
}); });
// create a sync event to identify server application startup // create a global sync event to identify server application startup
sync.AddSyncEvent(-1, "Application", -1); sync.AddSyncEvent(-1, "Application", -1, true);
} }
} }
} }

View File

@ -58,6 +58,16 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public string SiteGuid { get; set; } public string SiteGuid { get; set; }
/// <summary>
/// The hosting model for the site (ie. Server or WebAssembly ).
/// </summary>
public string Runtime { get; set; }
/// <summary>
/// The render mode for the site (ie. Server, ServerPrerendered, WebAssembly, WebAssemblyPrerendered ).
/// </summary>
public string RenderMode { get; set; }
#region IAuditable Properties #region IAuditable Properties
/// <inheritdoc/> /// <inheritdoc/>

View File

@ -14,6 +14,7 @@ namespace Oqtane.Models
public int TenantId { get; set; } public int TenantId { get; set; }
public string EntityName { get; set; } public string EntityName { get; set; }
public int EntityId { get; set; } public int EntityId { get; set; }
public bool Reload { get; set; }
public DateTime ModifiedOn { get; set; } public DateTime ModifiedOn { get; set; }
} }
} }

View File

@ -17,6 +17,8 @@ namespace Oqtane.Shared
public string DefaultTheme { get; set; } public string DefaultTheme { get; set; }
public string DefaultContainer { get; set; } public string DefaultContainer { get; set; }
public string DefaultAdminContainer { get; set; } public string DefaultAdminContainer { get; set; }
public string Runtime { get; set; }
public string RenderMode { get; set; }
public bool Register { get; set; } public bool Register { get; set; }
} }
} }