C
C#8mo ago
Apache

AspNetCore `net8.0` - Blazor {*CatchAll} route overrides MVC AdminController route

I'm using a Blazor8 with OrchardCore as a de-coupled CMS. I want /admin* to be routed by Orchard, and the rest to be routed by Blazor. Using this as a basic working example: https://github.com/ApacheTech/BlazOrchard If I have a page with @page "/{*Slug}";, I want to give priority to /admin to run through the MVC Area controller. It seems that Blazor strips all power away from MVC to route itself. I want Blazor to be the fallback.
GitHub
GitHub - ApacheTech/BlazOrchard: This repo gives an example of how ...
This repo gives an example of how to set up a solution to run an OrchardCore Decoupled CMS, with a Blazor Web App front-end. - ApacheTech/BlazOrchard
1 Reply
Apache
ApacheOP8mo ago
There is no manual mapping here, other than Blazor. Would I need to map the admin area separately. If so, in which part?
using BlazOrchard.BlazorWebApp.Components;
using OrchardCore.Logging;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Host.UseNLogHost();
builder.Services
.AddOrchardCms()
.ConfigureServices(services =>
{
services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
})
.Configure((app, routes, _) =>
{
app.UseStaticFiles();
app.UseAntiforgery();
routes.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(BlazOrchard.BlazorWebApp.Client._Imports).Assembly);
})
;

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseOrchardCore();
app.Run();
using BlazOrchard.BlazorWebApp.Components;
using OrchardCore.Logging;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Host.UseNLogHost();
builder.Services
.AddOrchardCms()
.ConfigureServices(services =>
{
services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
})
.Configure((app, routes, _) =>
{
app.UseStaticFiles();
app.UseAntiforgery();
routes.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(BlazOrchard.BlazorWebApp.Client._Imports).Assembly);
})
;

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseOrchardCore();
app.Run();
This is the page I would like to have work.
@page "/{*Slug}";
@if(_contentItem is null)
{
<StatusCodeErrorPage StatusCode="@(404)" />
}
else
{
<DynamicComponent Type="_contentItemType" Parameters="_parameters" />
}

@code {
private Dictionary<string, object> _parameters = [];
private ContentItem? _contentItem;
private Type? _contentItemType;

[Parameter]
public string Slug { get; set; }

[Inject]
private IOrchardHelper Orchard { get; init; }

protected override async Task OnParametersSetAsync()
{
_contentItem = await Orchard.GetContentItemBySlugAsync(Slug);
if (_contentItem is null) return;
_parameters["ContentItem"] = _contentItem;
_contentItemType = GetType().Assembly
.GetTypes()
.Where(p => !p.IsAbstract && p.IsSubclassOf(typeof(CsmHostedComponentBase)))
.SingleOrDefault(p => p.Name == _contentItem.ContentType);
StateHasChanged();
}
}
@page "/{*Slug}";
@if(_contentItem is null)
{
<StatusCodeErrorPage StatusCode="@(404)" />
}
else
{
<DynamicComponent Type="_contentItemType" Parameters="_parameters" />
}

@code {
private Dictionary<string, object> _parameters = [];
private ContentItem? _contentItem;
private Type? _contentItemType;

[Parameter]
public string Slug { get; set; }

[Inject]
private IOrchardHelper Orchard { get; init; }

protected override async Task OnParametersSetAsync()
{
_contentItem = await Orchard.GetContentItemBySlugAsync(Slug);
if (_contentItem is null) return;
_parameters["ContentItem"] = _contentItem;
_contentItemType = GetType().Assembly
.GetTypes()
.Where(p => !p.IsAbstract && p.IsSubclassOf(typeof(CsmHostedComponentBase)))
.SingleOrDefault(p => p.Name == _contentItem.ContentType);
StateHasChanged();
}
}
Then all my components would be at /Components/ContentTypes/{nameof(ContentType)}.razor, and inherit from CmsHostedComponentBase that supplies access to the helper, and other injected tools, as standard. But, using this, calls to /admin result in the 404 component showing. MVC is ignored. I thought that catch-all routes were supposed to have lowest priority.
Want results from more Discord servers?
Add your server