Apache
Apache
CC#
Created by Apache on 4/17/2024 in #help
AspNetCore `net8.0` - Blazor {*CatchAll} route overrides MVC AdminController route
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.
3 replies
CC#
Created by Apache on 4/17/2024 in #help
AspNetCore `net8.0` - Blazor {*CatchAll} route overrides MVC AdminController route
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();
3 replies
CC#
Created by Apache on 4/11/2024 in #help
Migrating WSDL imports via ServiceDescriptionImporter from Framework to Core
The answer to this question is pretty much exactly what we are doing now, and need to move away from: https://stackoverflow.com/questions/38482849/generating-proxy-class-from-wsdl-on-the-fly
34 replies
CC#
Created by Apache on 4/11/2024 in #help
Migrating WSDL imports via ServiceDescriptionImporter from Framework to Core
There's a System.Web.Services.Description NuGet package, but it doesn't contain ServiceDescriptionImporter, only ServiceDescription.
34 replies
CC#
Created by Apache on 4/11/2024 in #help
Migrating WSDL imports via ServiceDescriptionImporter from Framework to Core
But the code samples are programmatically built from the SOAP objects.
34 replies
CC#
Created by Apache on 4/11/2024 in #help
Migrating WSDL imports via ServiceDescriptionImporter from Framework to Core
The reference docs have code samples, and live demos. The live demos can use REST, that's fine.
34 replies
CC#
Created by Apache on 4/11/2024 in #help
Migrating WSDL imports via ServiceDescriptionImporter from Framework to Core
The services themselves are not being touched. All I'm doing is migrating the API reference docs, from Umbraco, to OrchardCore, with a Blazor de-coupled front-end.
34 replies
CC#
Created by DannyRoastBeef㊙ on 4/10/2024 in #help
(Blazor) I'm having trouble accessing a variable inside a parent component.
That shows how to use, set, and store, using cascading state management.
4 replies
CC#
Created by DannyRoastBeef㊙ on 4/10/2024 in #help
(Blazor) I'm having trouble accessing a variable inside a parent component.
Consumer.razor
<FluentButton OnClick="ToggleMenuBarAsync" Appearance="@ButtonAppearance">
@($"{(_sidebarExpanded ? "Expand" : "Collapse")} Sidebar");
</FluentButton>

@code{
private bool _sidebarExpanded = false;

[CascadingParameter]
private AppStateProvider AppState { get; init; }

private Appearance ButtonAppearance => _sidebadExpanded
? Appearance.Accent
: Appearance.Neutral;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
_sidebarExpanded = AppState.Current.SidebarExpanded;
}

private async Task ToggleMenuBarAsync()
{
if (!firstRender) return;
AppState.Current.SidebarExpanded = (_sidebarExpanded = !_sidebarExpanded);
await AppState.SaveChangesAsync();
}
}
<FluentButton OnClick="ToggleMenuBarAsync" Appearance="@ButtonAppearance">
@($"{(_sidebarExpanded ? "Expand" : "Collapse")} Sidebar");
</FluentButton>

@code{
private bool _sidebarExpanded = false;

[CascadingParameter]
private AppStateProvider AppState { get; init; }

private Appearance ButtonAppearance => _sidebadExpanded
? Appearance.Accent
: Appearance.Neutral;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
_sidebarExpanded = AppState.Current.SidebarExpanded;
}

private async Task ToggleMenuBarAsync()
{
if (!firstRender) return;
AppState.Current.SidebarExpanded = (_sidebarExpanded = !_sidebarExpanded);
await AppState.SaveChangesAsync();
}
}
4 replies
CC#
Created by DannyRoastBeef㊙ on 4/10/2024 in #help
(Blazor) I'm having trouble accessing a variable inside a parent component.
The Expanded, and ExpandedChanged parameters are the two halves of the two-way binding that you are setting up with @bind-Expanded. From what I understand from your explanation, you want to have a wider scope of access to the state of the Sidebar than you currently do. Are you persisting this value anywhere, i.e. as a cookie, or in local storage? What you are describing is "State Management". This is a hot topic within any web stack, and there are many ways to achieve it. There are three main objectives with state management: 1. Setting the state 2. Getting the state 3. Persisting the state You can use local storage to persist the state; bearing in mind that you don't have access to local storage until OnAfterRenderAsync. To get/set the state, you can use a CascadingValue component that you then call in the children with [CascadingParameter]. AppStateProvider.razor
<CascadingValue Value="this">
@ChildContent
</CascadingValue>

@code {
private const string _storageKey = ".ProjectName.AppState";

[Parameter]
public RenderFragment? ChildContent { get; set; }

[Inject]
private ProtectedLocalStorage LocalStorage { get; init; }

public AppState Current { get; private set; } = new();

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
var result = await LocalStorage.GetAsync<AppState>(_storageKey);
if (result.Success) Current = result.Value;
}

public async Task SaveChangesAsync()
{
await LocalStorage.SaveAsync(_storageKey, Current);
StateHasChanged();
}
}
<CascadingValue Value="this">
@ChildContent
</CascadingValue>

@code {
private const string _storageKey = ".ProjectName.AppState";

[Parameter]
public RenderFragment? ChildContent { get; set; }

[Inject]
private ProtectedLocalStorage LocalStorage { get; init; }

public AppState Current { get; private set; } = new();

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
var result = await LocalStorage.GetAsync<AppState>(_storageKey);
if (result.Success) Current = result.Value;
}

public async Task SaveChangesAsync()
{
await LocalStorage.SaveAsync(_storageKey, Current);
StateHasChanged();
}
}
AppState.cs
public class AppState
{
public bool SidebarExpanded { get; set; }
}
public class AppState
{
public bool SidebarExpanded { get; set; }
}
DISCLAIMER: This is written in Discord, and is untested, there may be syntax errors.
4 replies
CC#
Created by Häng on 4/11/2024 in #help
Disable Blazor NavLink
AdvancedNavLink.razor:
@(Disabled)
{
<div class="@DisabledClass">
@ChildContent
</div>
}
else
{
<NavLink href="@Href" class="@Class" ActiveClass="@ActiveClass" Match="@Match">
@ChildContent
</NavLink>
}

@code {
[Parameter]
public RenderFragment ChildContent { get; set; }

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

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

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

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

[Parameter]
public NavLinkMatch Match { get; set; }

[Parameter]
public bool Disabled { get; set; }
}
@(Disabled)
{
<div class="@DisabledClass">
@ChildContent
</div>
}
else
{
<NavLink href="@Href" class="@Class" ActiveClass="@ActiveClass" Match="@Match">
@ChildContent
</NavLink>
}

@code {
[Parameter]
public RenderFragment ChildContent { get; set; }

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

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

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

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

[Parameter]
public NavLinkMatch Match { get; set; }

[Parameter]
public bool Disabled { get; set; }
}
Usage:
<AdvancedNavLink Disabled="@_disableLinks"
Href="https://..."
Class="text-lg font-semibold"
ActiveClass="text-lg font-bold text-blue-700"
DisabledClass="text-lg font-medium text-grey-300">
Click Me!
</AdvancedNavLink>
<AdvancedNavLink Disabled="@_disableLinks"
Href="https://..."
Class="text-lg font-semibold"
ActiveClass="text-lg font-bold text-blue-700"
DisabledClass="text-lg font-medium text-grey-300">
Click Me!
</AdvancedNavLink>
8 replies
CC#
Created by Apache on 3/29/2024 in #help
CROSS APPLY within LINQ
I know it's the same code. It's that everywhere in the codebase uses method chaining, and we would like to keep it that way. I've solved it with method chaining by having a separate foreach loop after it's been enumerated, but there should be a way to do it properly. This seems like giving up. I would like to find a tool that can show the SQL above, as LINQ. Similar to how you can change between C#/VB/IL with dnSpy. LIke LinqPad, but in reverse.
6 replies
CC#
Created by Apache on 3/29/2024 in #help
CROSS APPLY within LINQ
I have seen that Stack Overflow reply. Is there a way with method chaining?
6 replies