A) AuthServer discovery shows HTTP endpoints (Angular rejects them) B) ABP Studio interception cannot reach cluster services (timeouts to Postgres/Redis via WireGuard)
Fix A – make discovery document fully HTTPS behind ingress/reverse proxy
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var env = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
if (!env.IsDevelopment())
{
// Honor X-Forwarded-* to build correct HTTPS URLs and cookies
context.Services.Configure<ForwardedHeadersOptions>(o =>
{
o.ForwardedHeaders = ForwardedHeaders.XForwardedFor
| ForwardedHeaders.XForwardedProto
| ForwardedHeaders.XForwardedHost;
o.KnownNetworks.Clear();
o.KnownProxies.Clear();
});
}
// If you cannot keep RequireHttpsMetadata=true, add this to avoid OpenIddict rejecting HTTP (not recommended for production):
if (!configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"))
{
Configure<OpenIddictServerAspNetCoreOptions>(options =>
{
options.DisableTransportSecurityRequirement = true;
});
}
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (!env.IsDevelopment())
{
app.UseForwardedHeaders();
}
// Optional hard override if your proxy doesn’t forward scheme correctly:
// app.Use((ctx, next) => { ctx.Request.Scheme = "https"; return next(); });
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseConfiguredEndpoints();
}
Fix B – ABP Studio interception timeouts to in-cluster services
Notes specific to Angular and GW
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Root cause
Fix: publish and copy the correct output into the runtime image
# Build & publish
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish ./src/YourCompany.YourApp.Blazor/YourCompany.YourApp.Blazor.csproj -c Release -o /app/publish
# Runtime
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "YourCompany.YourApp.Blazor.dll"]
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
WORKDIR /app
COPY ./src/YourCompany.YourApp.Blazor/bin/Release/net10.0/publish/ .
ENTRYPOINT ["dotnet", "YourCompany.YourApp.Blazor.dll"]
Verify that the path exists locally and contains the “_framework” under wwwroot/_framework or in static web assets folders included by the publish output.
Additional checks
ABP-specific note
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
What’s happening:
End-to-end steps to call protected APIs from your Next.js app using the SSO token:
${process.env.NEXT_PUBLIC_API_URL}/api/identity/my-profile, {
headers: {
Authorization: Bearer ${accessToken},
'Accept-Language': 'en', // optional
'Abp-TenantId': tenantId ?? '' // if you use multi-tenancy and need to target a tenant
}
});
if (res.status === 401) {
// handle re-auth or token refresh
}Minimal code example (server-side Next.js API route proxying to ABP API):
// /pages/api/me.ts
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const accessToken = req.headers['authorization']?.toString().replace(/^Bearer\s+/i, '');
if (!accessToken) {
return res.status(401).json({ error: 'No access token' });
}
const apiUrl = process.env.NEXT_PUBLIC_API_URL; // e.g. https://localhost:44350
const r = await fetch(`${apiUrl}/api/identity/my-profile`, {
headers: { Authorization: `Bearer ${accessToken}` }
});
if (!r.ok) {
return res.status(r.status).send(await r.text());
}
return res.status(200).json(await r.json());
}
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Do this to make it work reliably in MVC Razor Pages:
Ensure static JS proxies are enabled and generated
Use the new global namespace when calling APIs
Verify the actual namespace at runtime
Common pitfalls to check
Minimal working example // 1) After correct proxy generation and layout setup: // window.myCompany.myApp.default.bangGiaVeNgays.bangGiaVeNgays.create({ ... }) window.myCompany.myApp.default.bangGiaVeNgays.bangGiaVeNgays .getList({ skipCount: 0, maxResultCount: 10 }) .then(result => console.log(result)) .catch(err => console.error(err));
Does the latest ABP still support calling services like before?
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The call bypasses ABP’s interception pipeline. Checklist:
Auditing middleware and options
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseAuditing();
}
Configure<AbpAuditingOptions>(options =>
{
options.IsEnabled = true;
// optional:
// options.IsEnabledForGetRequests = true;
// options.AlwaysLogOnException = true;
});
Ensure you didn’t use [DisableAuditing] on the service or method.
Entity change logs require UoW + change tracking selection Create/Update “action logs” should appear even without entity changes, but if you expect EntityChanges, ensure:
Configure<AbpAuditingOptions>(options =>
{
options.EntityHistorySelectors.AddAllEntities(); // or add your entity types explicitly
});
Your DbContext is not being saved outside ABP’s UoW unexpectedly.
Verify the proxy is actually used in Blazor Temporarily assert interception by forcing auditing:
[Audited]
public class SeasonAppService : CrudAppService<Season, SeasonDto, Guid, PagedAndSortedResultRequestDto, CreateSeasonDto, UpdateSeasonDto>,
ISeasonAppService
{
public override async Task<SeasonDto> CreateAsync(CreateSeasonDto input) { ... }
public override async Task<SeasonDto> UpdateAsync(Guid id, UpdateSeasonDto input) { ... }
}
If this still doesn’t create an audit log, interception is likely bypassed.
public override async Task<SeasonDto> CreateAsync(CreateSeasonDto input)
{
return await base.CreateAsync(input);
}
public override async Task<SeasonDto> UpdateAsync(Guid id, UpdateSeasonDto input)
{
return await base.UpdateAsync(id, input);
}
Do not seal the class or methods.
[Inject] protected ISeasonAppService SeasonAppService { get; set; } = default!;
Do not cast to the concrete type or call non-virtual helpers on the class.
Custom IAuditingStore If you replaced IAuditingStore, ensure SaveAsync is called and not filtering out Create/Update. Log inside your store to verify it’s invoked for Create/Update paths.
Quick diagnostic
If after all checks Delete is audited but Create/Update are not:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Fixes (apply all that match your case):
public partial class MyPage : ComponentBase
{
// Good: inject the interface that inherits IApplicationService
[Inject] private IMyEntityAppService MyEntityAppService { get; set; } = default!;
private async Task SaveAsync(CreateMyEntityDto input)
{
await MyEntityAppService.CreateAsync(input); // audited by proxy
}
}
Ensure your interface implements IApplicationService:
public interface IMyEntityAppService : IApplicationService
{
Task<MyEntityDto> CreateAsync(CreateMyEntityDto input);
Task<MyEntityDto> UpdateAsync(Guid id, UpdateMyEntityDto input);
Task DeleteAsync(Guid id);
Task<PagedResultDto<MyEntityDto>> GetListAsync(PagedAndSortedResultRequestDto input);
}
Do not inject the concrete class into the Blazor page/component. If you must access implementation-only members, expose them via the interface or use a domain service behind the app service.
Ensure auditing is enabled for app service methods:
Configure<AbpAuditingOptions>(options =>
{
options.IsEnabled = true;
options.IsEnabledForGetRequests = true; // optional
options.AlwaysLogOnException = true;
// Track entity changes if needed:
options.EntityHistorySelectors.AddAllEntities();
});
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseAuditing();
}
Ensure the UoW is active and SaveChanges happens inside the same call so EntityChange logs are produced. Using standard repositories inside application services with ABP’s UnitOfWork ensures that. Avoid calling repositories outside of an app-service/UoW boundary.
Confirm you are not suppressing interceptors:
If you have replaced IAuditingStore or use a remote store, ensure SaveAsync is called; check logs of your auditing store.
Quick verification
[Audited]
public class MyEntityAppService : ApplicationService, IMyEntityAppService
{
public virtual async Task<MyEntityDto> CreateAsync(CreateMyEntityDto input) { ... }
}
If you instead prefer calling over HTTP even from Blazor Server, you can inject the dynamic C# client (HttpApi.Client) for the same interface. That path always goes through the server pipeline and auditing.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
A) Use the official Version Mapping inside ABP Studio (recommended)
B) Use the supported “switch version” script pattern but only with existing packages
param (
[string]$version = "1.4.2",
[string]$channel = "release"
)
$installdir = "$env:LOCALAPPDATA\abp-studio\"
$file = "abp-studio-$version-$channel-full.nupkg"
$url = "https://abp.io/api/abp-studio/r/download/windows/$file" # note the '/r/download/windows' path used by the official updater logs
$pkgDir = "$installdir\packages"
$outputPath = Join-Path $pkgDir $file
Write-Host "Installing to $installdir"
if (-not (Test-Path $pkgDir)) { New-Item -ItemType Directory -Path $pkgDir -Force | Out-Null }
try {
$resp = Invoke-WebRequest -Uri $url -Method Head -UseBasicParsing -ErrorAction Stop
} catch {
Write-Error "Package not found on feed: $url. Please choose another Studio version present on the feed."
exit 1
}
if (-not (Test-Path $outputPath)) {
Write-Host "Downloading $url to $outputPath"
Invoke-WebRequest -Uri $url -OutFile $outputPath -UseBasicParsing
} else {
Write-Host "File already present: $outputPath"
}
$updateExe = Join-Path $installdir "Update.exe"
Write-Host "Applying package..."
& $updateExe apply --package $outputPath
Write-Host "Done."
C) Use ABP Studio CLI aligned to 9.3.6
Notes
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
ABP Studio 1.4.2 is the correct Studio version to generate solutions with ABP 9.3.6 (per the official mapping).
The 404 happens because the package name you’re trying to download is wrong. Studio 1.4.2 is a stable release, not beta. Use the stable “release” channel package name:
Quick fix for the script:
param (
[string]$version = "1.4.2",
[string]$channel = "release"
)
$installdir = "$env:LOCALAPPDATA\abp-studio\"
Write-Host "Installing to $installdir"
$file = "abp-studio-$version-$channel-full.nupkg"
$url = "https://abp.io/api/abp-studio/download/r/windows/$file"
$outputPath = "$installdir\packages\$file"
if (-not (Test-Path $installdir)) { New-Item -ItemType Directory -Path $installdir -Force | Out-Null }
if (-not (Test-Path "$installdir\packages")) { New-Item -ItemType Directory -Path "$installdir\packages" -Force | Out-Null }
if (Test-Path $outputPath) {
Write-Host "File $file already exists. Skipping download."
} else {
Write-Host "Downloading $url to $outputPath"
Invoke-WebRequest -Uri $url -OutFile $outputPath
}
$updateExe = "$installdir\Update.exe"
Write-Host "Running $updateExe apply --package $outputPath"
& $updateExe apply --package $outputPath
Write-Host "ABP Studio version $version ($channel) installed successfully."
After installation:
Alternative (without Studio UI): You can also use ABP Studio CLI of that version to create the project in a CI/terminal environment. Ensure the Studio CLI version aligns with 1.4.2 (bundled with Studio), then run abp new with your template options. However, using the Studio UI 1.4.2 is simpler since it already binds to 9.3.6.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
context.Menu.AddItem(
new ApplicationMenuItem(
"MyHome",
"Home",
url: "/",
icon: "fa fa-home",
order: 0
)
);
- If you customize the built-in Home item, ensure its Url is “/” (not null/empty).
var url = string.IsNullOrWhiteSpace(MenuItem.MenuItem.Url)
? "/"
: MenuItem.MenuItem.Url.TrimStart('/', '~');
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Verify and fix with the checklist below.
A) Ensure dynamic JS proxy is enabled
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(KSVRApplicationModule).Assembly);
});
Configure<AbpAspNetCoreMvcClientProxyOptions>(options =>
{
// default is dynamic proxies ON; ensure not disabled globally
// options.DisableAbpDynamicProxyScript = false; // only if you had set it true somewhere
});
B) Load the dynamic proxy script on the page
<script src="~/Abp/ApplicationConfigurationScript"></script>
<script src="~/Abp/ServiceProxyScript"></script>
<script src="~/libs/jquery/jquery.js"></script>
<script src="~/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- ... other abp libs -->
<script src="~/Pages/BangGiaVeNgays/index.js"></script>
C) Confirm correct Root Namespace in JS
var bangGiaVeNgayService = window.webCMS.KSVR.services.bangGiaVeNgays.bangGiaVeNgays;
This will only work if:
D) Ensure your AppService is exposed to HTTP (so proxy can be generated)
[RemoteService(true)]
public class BangGiaVeNgayAppService : ApplicationService, IBangGiaVeNgayAppService
{
// ...
}
E) If it’s a tiered setup (Auth Server separated)
"RemoteServices": {
"Default": {
"BaseUrl": "https://localhost:443xx" // your HttpApi.Host
}
}
"RemoteServices": {
"Default": {
"BaseUrl": "https://localhost:443xx"
},
"KSVR": {
"BaseUrl": "https://localhost:443xx"
}
}
F) Confirm the final JS object path
G) Common pitfalls to fix
Once the above are corrected, the line like below should work without error:
var l = abp.localization.getResource('KSVR');
var bangGiaVeNgayService = window.WebCMS.KSVR.services.bangGiaVeNgays.bangGiaVeNgays;
bangGiaVeNgayService.getList({ filter: '...' }).then(res => {
// ...
});
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.