✨ Managed mode page will render with layout
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Zone.Pages.Dynamic;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -8,8 +16,14 @@ namespace DysonNetwork.Zone.Publication;
|
||||
public class PublicationSiteMiddleware(RequestDelegate next)
|
||||
{
|
||||
public const string SiteContextKey = "PubSite";
|
||||
|
||||
public async Task InvokeAsync(HttpContext context, AppDatabase db, PublicationSiteManager psm)
|
||||
|
||||
public async Task InvokeAsync(
|
||||
HttpContext context,
|
||||
AppDatabase db,
|
||||
PublicationSiteManager psm,
|
||||
IRazorViewEngine viewEngine,
|
||||
ITempDataProvider tempData
|
||||
)
|
||||
{
|
||||
var siteNameValue = context.Request.Headers["X-SiteName"].ToString();
|
||||
var currentPath = context.Request.Path.Value ?? "";
|
||||
@@ -21,7 +35,8 @@ public class PublicationSiteMiddleware(RequestDelegate next)
|
||||
}
|
||||
|
||||
var site = await db.PublicationSites
|
||||
.FirstOrDefaultAsync(s => EF.Functions.ILike(s.Slug, siteNameValue));
|
||||
.FirstOrDefaultAsync(s => EF.Functions.ILike(s.Slug, siteNameValue)
|
||||
);
|
||||
if (site == null)
|
||||
{
|
||||
await next(context);
|
||||
@@ -29,7 +44,7 @@ public class PublicationSiteMiddleware(RequestDelegate next)
|
||||
}
|
||||
|
||||
context.Items[SiteContextKey] = site;
|
||||
|
||||
|
||||
var page = await db.PublicationPages
|
||||
.FirstOrDefaultAsync(p => p.SiteId == site.Id && p.Path == currentPath);
|
||||
if (page != null)
|
||||
@@ -38,13 +53,31 @@ public class PublicationSiteMiddleware(RequestDelegate next)
|
||||
{
|
||||
case PublicationPageType.HtmlPage
|
||||
when page.Config.TryGetValue("html", out var html) && html is JsonElement content:
|
||||
context.Response.ContentType = "text/html";
|
||||
await context.Response.WriteAsync(content.ToString());
|
||||
if (site.Mode == PublicationSiteMode.FullyManaged)
|
||||
{
|
||||
context.Items["PublicationHtmlContent"] = content.ToString();
|
||||
var layoutedHtml = await RenderViewAsync(
|
||||
context,
|
||||
viewEngine,
|
||||
tempData,
|
||||
"/Pages/Dynamic/DynamicPage.cshtml",
|
||||
new DynamicPage { Html = content.ToString() }
|
||||
);
|
||||
context.Response.ContentType = "text/html";
|
||||
await context.Response.WriteAsync(layoutedHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.ContentType = "text/html";
|
||||
await context.Response.WriteAsync(content.ToString());
|
||||
}
|
||||
return;
|
||||
case PublicationPageType.Redirect
|
||||
when page.Config.TryGetValue("target", out var tgt) && tgt is JsonElement redirectUrl:
|
||||
context.Response.Redirect(redirectUrl.ToString());
|
||||
return;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,4 +118,51 @@ public class PublicationSiteMiddleware(RequestDelegate next)
|
||||
|
||||
await next(context);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> RenderViewAsync(
|
||||
HttpContext context,
|
||||
IRazorViewEngine engine,
|
||||
ITempDataProvider tempDataProvider,
|
||||
string viewPath,
|
||||
object model)
|
||||
{
|
||||
var endpointFeature = context.Features.Get<IEndpointFeature>();
|
||||
var endpoint = endpointFeature?.Endpoint;
|
||||
|
||||
var routeData = context.GetRouteData();
|
||||
|
||||
var actionContext = new ActionContext(
|
||||
context,
|
||||
routeData,
|
||||
new ActionDescriptor()
|
||||
);
|
||||
|
||||
await using var sw = new StringWriter();
|
||||
|
||||
var viewResult = engine.GetView(null, viewPath, true);
|
||||
|
||||
if (!viewResult.Success)
|
||||
throw new FileNotFoundException($"View '{viewPath}' not found.");
|
||||
|
||||
var viewData = new ViewDataDictionary(
|
||||
new EmptyModelMetadataProvider(),
|
||||
new ModelStateDictionary())
|
||||
{
|
||||
Model = model
|
||||
};
|
||||
|
||||
var tempData = new TempDataDictionary(context, tempDataProvider);
|
||||
|
||||
var viewContext = new ViewContext(
|
||||
actionContext,
|
||||
viewResult.View,
|
||||
viewData,
|
||||
tempData,
|
||||
sw,
|
||||
new HtmlHelperOptions()
|
||||
);
|
||||
|
||||
await viewResult.View.RenderAsync(viewContext);
|
||||
return sw.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user