I have a dynamic rewrite mechanism.
In a table that I called Rewrite I store all keys and respectively the page and parameters I have to call.
For example:
Key | Page | Red | Green | Blue |
---|---|---|---|---|
red-products | Products | 255 | 0 | 0 |
green-products | Products | 0 | 255 | 0 |
In my Products.razor page the page directive is
@page/{red}/{green}/{blue}
and I have
[Parameter]
public string red{ get; set; }
[Parameter]
public string green{ get; set; }
[Parameter]
public string blue{ get; set; }
In My Index.razor there is the start of this mechanism.
so it has this page directive
@page "/"
@page "/{key}"
In Index.razor.cs I have
public partial class Index : BaseComponent
{
[Parameter]
public string key { get; set; }
[Inject] protected HttpClient Http { get; set; }
[Inject] protected NavigationManager NavigationManager { get; set; }
protected override async Task OnParametersSetAsync()
{
if (key != null)
{
Rewrite r = await Http.GetFromJsonAsync<Rewrite>($"api/Rewrite/GetRewriteByKey/{0}/{key}");
NavigationManager.NavigateTo($"{r.Page}/{r.Red}/{r.Green}/{r.Blue}");
}
base.OnParametersSet();
}
}
What I want to do is call Product page without changing url in browser, so keep pred-products in browser url but call Products page with parameters 255,0,0.
Is it Possible? or is there a smarter way to handle these rewrites?
In Asp.net web forms I'm using the same reasoning in the file global.asax and I use the command
Context.RewritePath($"{r.Page}/{r.Red}/{r.Green}/{r.Blue}");
If I've understood your question correctly, you can use DynamicComponent
to manage your Page.
The following code should demostrates hoe to use it.
A Data Provider to provide the data - your API call.
namespace SO77439144.Components.Pages;
public record MyData(string Key, string ClassName, int Red, int Green, int Blue);
public class DataProvider
{
public IEnumerable<MyData> Items => _items.AsEnumerable();
public ValueTask<MyData?> GetDataAsync(string key)
=> ValueTask.FromResult( _items.FirstOrDefault(x => x.Key == key));
private List<MyData> _items = new()
{
new("red-products", "SO77439144.Components.Pages.Products", 255,0,0),
new("green-products", "SO77439144.Components.Pages.Products", 0,255,0),
new("blue-products", "SO77439144.Components.Pages.Products", 0,0,255),
};
}
Registered as a service.
The Products
component:
<h3>Products</h3>
<div>
<pre>Red : @Red</pre>
<pre>Green : @Green</pre>
<pre>Blue : @Blue</pre>
</div>
@code {
[Parameter]
public int Red { get; set; }
[Parameter]
public int Green { get; set; }
[Parameter]
public int Blue { get; set; }
}
And Index:
@page "/"
@page "/key/{Key}"
@using System.Reflection
@inject DataProvider Provider
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
@if (_componentType is not null)
{
<DynamicComponent Type="_componentType" Parameters="_componentProperties" />
}
@code {
[Parameter] public string? Key { get; set; }
private string? _key;
private MyData? _data;
private Dictionary<string, object> _componentProperties => new() {
{"red", _data?.Red ?? 0},
{"green", _data?.Green ?? 0},
{"blue", _data?.Blue ?? 0},
};
private Type? _componentType;
protected async override Task OnParametersSetAsync()
{
if (_key == this.Key)
return;
_key = this.Key;
if (_key is not null)
{
_data = await Provider.GetDataAsync(_key);
_componentType = this.GetComponentType(_data.ClassName);
}
}
private Type? GetComponentType(string className)
{
var assembly = Assembly.GetExecutingAssembly();
var instance = assembly.CreateInstance(className);
return instance?.GetType() ?? null;
}
}
Paths are then https://localhost:7123/key/red-products etc.