diff --git a/src/BlazeKit.Static/BlazeKit.Static.csproj b/src/BlazeKit.Static/BlazeKit.Static.csproj index 21f0444..6beed68 100644 --- a/src/BlazeKit.Static/BlazeKit.Static.csproj +++ b/src/BlazeKit.Static/BlazeKit.Static.csproj @@ -8,13 +8,13 @@ - + diff --git a/src/BlazeKit.Web/BlazeKit.Web.csproj b/src/BlazeKit.Web/BlazeKit.Web.csproj index 82b67c4..415352c 100644 --- a/src/BlazeKit.Web/BlazeKit.Web.csproj +++ b/src/BlazeKit.Web/BlazeKit.Web.csproj @@ -13,6 +13,7 @@ + diff --git a/src/BlazeKit.Web/Components/PageComponentBase.cs b/src/BlazeKit.Web/Components/PageComponentBase.cs index ed715d0..6a20573 100644 --- a/src/BlazeKit.Web/Components/PageComponentBase.cs +++ b/src/BlazeKit.Web/Components/PageComponentBase.cs @@ -1,12 +1,15 @@ using BlazeKit.Hydration; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.AspNetCore.Http; namespace BlazeKit.Web.Components; public abstract class PageComponentBase : IComponent, IPageLoad where TResult : PageDataBase { [Inject] required public DataHydrationContext HydrationContext { get; init; } - + [Inject] required public NavigationManager NavigationManager { get; init; } + [CascadingParameter] private HttpContext? Context { get; set; } + private RenderFragment renderFragment; private readonly string dataKey; private RenderHandle renderHandle; @@ -54,7 +57,8 @@ public async Task SetParametersAsync(ParameterView parameters) if(IsServer()) { - var data = await this.ServerLoadAsync(); + var route = new Uri(NavigationManager.Uri); + var data = await this.ServerLoadAsync(route, Context); if(data != null) { this.data = data; @@ -79,27 +83,12 @@ protected virtual void BuildRenderTree(RenderTreeBuilder builder) // but instead should invoke the _renderFragment field. } - protected virtual Task ServerLoadAsync() + protected virtual Task ServerLoadAsync(Uri route, HttpContext? context) { return Task.FromResult(default(TResult)); } - void Render(RenderTreeBuilder builder) - { - // decorate the ChildContent with a CascadingValue contianing the PageData - builder.OpenComponent>(0); - builder.AddComponentParameter(1, "Value", this.PageData); - builder.AddComponentParameter(1, "Name", "PageData"); - builder.AddComponentParameter(2, "ChildContent", renderFragment); - builder.CloseComponent(); - } - - protected Task LoadPageDataAsync(T fallback) - { - return HydrationContext.GetAsync(this.dataKey, fallback); - } - private bool IsServer() { return !OperatingSystem.IsBrowser(); diff --git a/src/BlazeKit.Web/IPageLoad.cs b/src/BlazeKit.Web/IPageLoad.cs index 8e77ef3..cb29994 100644 --- a/src/BlazeKit.Web/IPageLoad.cs +++ b/src/BlazeKit.Web/IPageLoad.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; namespace BlazeKit.Web; internal interface IPageLoad { - virtual Task ServerLoadAsync() => Task.FromResult(default(TPageData)); + virtual Task ServerLoadAsync(Uri route, HttpContext? context) => Task.FromResult(default(TPageData)); } diff --git a/src/BlazeKit.Web/Utils/UriExtensions.cs b/src/BlazeKit.Web/Utils/UriExtensions.cs new file mode 100644 index 0000000..b7eddfa --- /dev/null +++ b/src/BlazeKit.Web/Utils/UriExtensions.cs @@ -0,0 +1,29 @@ +namespace BlazeKit.Web.Utils +{ + public static class UriExtensions + { + public static string Param(this Uri uri, string name) + { + return Param(uri,name, () => throw new InvalidOperationException($"There is no query param with the name '{name}' in the route.")); + } + + public static string Param(this Uri uri, string name, string fallback) + { + return Param(uri,name, fallbackFunc: () => fallback); + } + + private static string Param(Uri uri, string name, Func fallbackFunc) + { + string result = string.Empty; + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + if (queryDictionary.HasKeys() && queryDictionary.AllKeys.Contains(name)) + { + result = queryDictionary[name]; + } else + { + result = fallbackFunc(); + } + return result; + } + } +} diff --git a/src/BlazeKit.Website/Routes/Docs/(Core-Concepts)/Loading-Data/Page.razor b/src/BlazeKit.Website/Routes/Docs/(Core-Concepts)/Loading-Data/Page.razor index 91533a4..f4b40eb 100644 --- a/src/BlazeKit.Website/Routes/Docs/(Core-Concepts)/Loading-Data/Page.razor +++ b/src/BlazeKit.Website/Routes/Docs/(Core-Concepts)/Loading-Data/Page.razor @@ -1,18 +1,28 @@ @using BlazeKit.Web.Components @using System.Diagnostics +@using BlazeKit.Web.Utils +@using Microsoft.AspNetCore.Http +@using Microsoft.AspNetCore.Authentication @inherits PageComponentBase @code { private const bool prerender = true; - protected override async Task ServerLoadAsync() + protected override async Task ServerLoadAsync(Uri route, HttpContext? context) { + Debug.WriteLine($"Page Load called for '{route}'."); + var people = route.Param("people", "1"); + + // Modify response headers. This only has effect when SSR is used. + // If the app is statically generated, the http context will be null and the code will not be executed. + context?.Response.Headers.Add("X-BLAZEKIT-DEBUG", "enabled"); + SwapiPageData result; using (var http = new HttpClient()) { Debug.WriteLine($"Load data from SWAPI"); http.BaseAddress = new Uri("https://swapi.dev/api/"); - var response = await http.GetAsync("people/1"); + var response = await http.GetAsync($"people/{people}"); response.EnsureSuccessStatusCode(); var json = System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStringAsync()); Debug.WriteLine($"Got response"); diff --git a/src/BlazeKit.Website/_Imports.razor b/src/BlazeKit.Website/_Imports.razor index e561b0c..b167c7f 100644 --- a/src/BlazeKit.Website/_Imports.razor +++ b/src/BlazeKit.Website/_Imports.razor @@ -13,3 +13,4 @@ @using Humanizer; @using BlazeKit.Website.Routes.Docs.Blazekit_CLI; @using BlazeKit.Hydration; +@using BlazeKit.Web.Utils;