Activities of "maliming"

Hi,

The latest Volo.Abp.Studio.Cli requires the .NET 10 SDK, so this error usually means the machine doesn't have it (or an older SDK is being used).

Could you run the command below and share the output?

dotnet --list-sdks

If .NET 10 is not in the list, install the .NET 10 SDK from https://dotnet.microsoft.com/en-us/download/dotnet/10.0

Then install the CLI from an empty folder with a global.json to make sure the .NET 10 SDK is used:

mkdir test
cd test
dotnet new globaljson --sdk-version 10.0.100 --roll-forward latestFeature
dotnet tool install -g Volo.Abp.Studio.Cli

After that, restart ABP Studio and it should pass the prerequisite check.

Thanks

Hi,

You're right, and this isn't something you did wrong. The React Native template currently uses Expo SDK 56, but the Expo Go app on the App Store is stuck at SDK 54 because Apple hasn't approved Expo's newer submissions for months. Expo explained the situation in this changelog post. Since iPhones can only install Expo Go from the App Store, an SDK 56 project can't be opened in Expo Go on a real device right now.

Until this is sorted out on the template side, you can downgrade the generated app to SDK 54. In the react-native folder, run:

npx expo install expo@^54.0.0
npx expo install --fix
yarn add react-native@0.81.5
yarn add -D @types/react@~19.1.10 typescript@~5.9.2

The separate react-native command is needed because the template excludes it from expo install --fix (see expo.install.exclude in package.json), so it has to be pinned manually. Also stick with yarn for this project (it ships a yarn.lock); npm install fails with a peer dependency conflict.

After that, yarn start and scan the QR code again - the project will report SDK 54 to Expo Go, matching the version supported by the App Store build.

We'll also review the Expo SDK version used by the template so this mismatch is handled on the template side as well.

Thanks

Hi,

Since this turned out to be a bug on our side, I've refunded your ticket. The Advanced-tab step above will unblock you for now, and the Suite fix is on the way for an upcoming release.

Thanks

Hi,

Thanks for sending the DLL — that made it clear, and this is a bug on our side in ABP Suite.

When you reference an entity from another module, the Basic tab builds the Display property list only from properties declared directly on the entity class. Suite generated your entity's properties on the CompanyBase class (your concrete Company inherits from it), so that list comes back empty, the Display property dropdown doesn't render, and the OK button never enables.

You can get past this right now without changing the entity:

  1. Select Company.
  2. Switch to the Advanced tab.
  3. In the Display property field there, type CompanyName (it's a free-text input, so it doesn't depend on that scan).
  4. Click OK.

That fills in the display property, the rest of the fields are already set, and the generated lookup will use the real CompanyName column — no extra property or database change needed.

We'll fix the Basic tab scan so it also picks up properties from the generated ...Base class.

Thanks

Answer

Hi,

You're right that in a layered or single-layer solution the Admin Console being a package you can't touch is the part that feels separate.

We're considering adding an option to include it as source in these templates, the way the microservice template already does. With that you could keep the Admin Console in your own solution and shape it like the rest of your app, while the default stays as the package for teams who'd rather keep it simple and upgradeable.

Thanks

Hi,

Your email hasn't reached me yet — could you send it through https://wetransfer.com instead (to liming.ma@volosoft.com)? Attachments on the support thread and email sometimes get stripped.

To pin this down, the most useful thing would be the Transaction solution that reproduces it (a trimmed-down copy is fine). If you'd rather not share the whole thing, these two are enough:

  1. The compiled WGBS_Connect.Domain.dll — the exact copy under your Transaction solution's src folder, since that's the one the dialog loads.
  2. The Company entity source file(s), including any base or partial class if Suite split it (e.g. Company.cs plus a ...Base.cs).

With those I can load the same DLL and see exactly why CompanyName isn't offered as a display property.

Thanks

Hi,

Thanks, that screenshot helps. CompanyName is there in the entity, so the source is fine.

The thing is, this dialog doesn't read your entity source — it loads the compiled WGBS_Connect.Domain.dll and reflects over it to build the Display property list. And Suite loads that DLL once per session and keeps it cached, so if it picked up an older build of the DLL (one from before CompanyName was added), it'll keep using that until Suite is restarted — which would leave the Display property empty and the OK button disabled, exactly like you're seeing.

Could you try this:

  1. Rebuild the Master Data module and make sure the WGBS_Connect.Domain.dll under your Transaction solution's src folder is the fresh one that includes CompanyName (if you reference the module as a NuGet package, repack/reinstall it, not just rebuild the source).
  2. Fully close ABP Suite and reopen it, then open the navigation property dialog again and select Company.

If CompanyName still doesn't show up as a display property after that, send me the compiled WGBS_Connect.Domain.dll (or a small repro project) at liming.ma@volosoft.com and I'll check it directly.

Thanks

Hi,

The OK button is disabled because the dialog needs a Display property and there's none to pick for Company. That's the property Suite uses as the visible text in the generated dropdown, and it's required — without it the button stays off.

The catch is that Suite only offers string properties declared directly on the entity itself as the display property. Inherited ones (like the base ConcurrencyStamp) don't count, which is why Company still shows up in the entity list but the Display property field is empty. Your Company entity doesn't have its own string property, so there's nothing to select.

To fix it, give Company a string property (e.g. Name) in the Master Data module, rebuild that module so the DLL your Transaction solution references is up to date, then reopen the dialog. Select Company again, pick the display property, and OK will be enabled.

Thanks

Hi,

You're right, there is no option or panel directive for this. In the side-menu layout the toolbar always lands in the right-hand strip, and neither provideSideMenuLayout() nor withLpxSideMenuOptions() can change where it goes.

The way to get what you want is to keep the side-menu layout as it is and restyle .lpx-toolbar-container so it sits in the topbar instead of the right strip. Add this to your global styles.scss:

@media only screen and (min-width: 768px) {
  .lpx-topbar {
    min-height: 48px;
    align-items: center;
  }

  .lpx-toolbar-container {
    position: absolute;
    top: 0;
    right: 0;
    bottom: auto;
    width: auto;
    min-height: 0;
    height: 48px;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.25rem;
    background-color: transparent;
  }

  .lpx-toolbar-container .lpx-toolbar,
  .lpx-toolbar-container .lpx-settings {
    position: static;
    width: auto;
    min-width: 0;
  }

  .lpx-toolbar-container nav.lpx-toolbar > .lpx-nav-menu,
  .lpx-toolbar-container .lpx-settings {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 1rem;
    margin: 0;
    padding: 0;
  }

  .lpx-toolbar-container .lpx-user-menu {
    margin: 0;
  }

  .lpx-toolbar-container .lpx-user-menu .lpx-menu-item-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: auto;
    width: auto;
    padding: 0;
  }

  .lpx-toolbar-container .lpx-user-menu .lpx-menu-item-link .lpx-menu-item-text {
    display: inline;
    width: auto !important;
    margin: 0;
    font-size: 0.875rem;
    line-height: 1;
    text-align: left;
  }

  .lpx-toolbar-container .lpx-user-menu .lpx-avatar .lpx-avatar-img,
  .lpx-toolbar-container .lpx-user-menu .lpx-avatar .lpx-avatar-icon {
    width: 28px;
    height: 28px;
    margin: 0;
    font-size: 15px;
    border-radius: 28px;
  }

  .lpx-toolbar-container .lpx-settings .setting-icon {
    height: auto;
    font-size: 1rem;
  }

  .lpx-toolbar-container .lpx-context-menu {
    top: 100%;
    right: 1.25rem;
    bottom: auto;
    margin: 0;
  }

  .lpx-content-container {
    margin-right: 0;
  }

  .lpx-footbar-container {
    right: 0;
  }
}

The avatar, the user context menu, the language and settings dropdowns all keep working — they are the same components, just laid out horizontally. A few notes on the rules, since most of them exist to undo something:

  • The default topbar is shorter than the toolbar row, so .lpx-topbar gets a min-height and centers its children.
  • .lpx-user-menu carries a margin-top, a fixed height: 72px link and a width: 72px !important label, all of it sized for the 72px vertical strip. Leave any of those in and the avatar sits ~10px below the settings icons and pushes the row out of the topbar.
  • The .lpx-nav-menu rules are scoped with nav.lpx-toolbar > on purpose. Drop that part and they also hit the menus inside the dropdowns, which then render as a full-width row.
  • The last two rules give the content area back the 72px that was reserved for the strip.
  • Everything sits in a min-width: 768px query, so the mobile navbar is untouched.

Tune height, gap and padding to taste. Since this overrides theme CSS, give it a quick look when you upgrade LeptonX.

On the hybrid layout as a built-in option — there is no plan for it at the moment.

Thanks

Hi,

The exception comes from endpoint routing. A broad route in your Blazor app — a page routed on something like /{__tenant} — also matches /signin-oidc, and Razor component endpoints accept POST and require antiforgery validation by default. The OIDC form_post callback is not an application form, so it carries no antiforgery token, and in the current pipeline that validation runs before the OpenID Connect handler gets to consume the callback.

Move app.UseAntiforgery() after both app.UseAuthentication() and app.UseAuthorization() in OnApplicationInitialization of your Blazor module:

app.UseRouting();
app.MapAbpStaticAssets();
app.UseAbpSecurityHeaders();
app.UseAuthentication();

if (MultiTenancyConsts.IsEnabled)
{
    app.UseMultiTenancy();
}

app.UseDynamicClaims();
app.UseAuthorization();
app.UseAntiforgery();

That is the placement ASP.NET Core requires, and it keeps antiforgery validation on your own Blazor forms — routing has already picked the endpoint, and the middleware still runs before the endpoint executes.

One more thing that comes with the route-based tenant approach, separate from the exception above: the antiforgery cookie takes its path from Request.PathBase. Once the tenant middleware sets PathBase = /Tenant1, the cookie is scoped to /Tenant1, and a form rendered under the tenant path but posted to a root path fails validation with a 400. Pin the path on each host where that happens:

using Microsoft.AspNetCore.Antiforgery;

context.Services.Configure<AntiforgeryOptions>(options =>
{
    options.Cookie.Path = "/";
});

Thanks

Showing 221 to 230 of 12912 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on November 02, 2026, 06:56
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.