扩展project.Web 顶部工具栏 NotificationBadge 的提示铃铛,使其点击后展开一个通知下拉面板。
将现有的“铃铛 + 数字徽章(轮询未读数)”改造为 LeptonX 风格的 lpx-context-menu 下拉通知中心:铃铛仅负责切换面板,面板内动态加载并展示最新的 4 条私信通知,按日期分组(TODAY / YESTERDAY / 具体日期),底部提供“See All Notifications”按钮跳转至完整的私信列表页 /notification/private-messages。
api/notification/private-message/unread-count)。abp.ajax 调用 api/notification/private-message(MaxResultCount=4,Sorting=CreationTime DESC)动态拉取最新 4 条私信。bi-bell-fill 成员图标样式,Title 作为高亮文本、Content 作为正文、日期/时间作为小字。/notification/private-messages。Default.cshtml) + 原生 JavaScript。lpx-* 类名与 Bootstrap Icons(bi);不引入新依赖、不需前端构建。abp.ajax / abp.event 模式,调用已存在接口。Default.cshtml 的标记与脚本,将其升级为“铃铛触发 + 下拉面板”结构;视图组件 NotificationBadgeViewComponent.cs 无需改动(仍返回 Default.cshtml)。<a> 改为 data-lpx-ctx-toggle="notification-bar",移除原 href 跳转,仅切换下拉;跳转职责迁移到底部按钮(<a href="/notification/private-messages"> 或 lpx-button 包链接)。lpx-context-menu + 顶部标题/关闭(data-lpx-close)+ 分组容器(首次为空,由 JS 注入)+ 底部按钮。lpx-notification-member-icon bi bi-bell-fill),以 Title 作为 lpx-notification-text-highlight、Content 作为正文。unreadCount 将前 N 条标记为 unread(提供红色侧边/未读视觉),属合理近似;不触发后端标记已读。window.__notificationPollTimer 清理与 abp.domUpdated 重渲染清理逻辑,防止 SPA 下定时器/事件重复绑定与内存泄漏。CreationTime 为 UTC,分组与展示以 new Date(item.creationTime) 的本地日期判断 Today/Yesterday。menu-item-badge 徽章样式与轮询;新增 fetchLatest():组装 URL (abp.appPath||'') + 'api/notification/private-message?maxResultCount=4&sorting=CreationTime%20DESC',abp.ajax GET,成功后将 result.items 渲染至面板。CreationTime 转为本地 Date,与“今天 00:00”“昨天 00:00”比较,归入 TODAY / YESTERDAY / YYYY.MM.DD 三类,按模板生成对应 outer-menu-item + lpx-menu-item-title + lpx-notification-items 区块。1h ago)或 HH:mm,非当天显示 HH:mm;可在 JS 内简单格式化。abp 未就绪,沿用现有 setInterval 重试 tryInit 机制初始化下拉加载与轮询。<script>)。apps/web/Project.Web/
└── Components/Toolbar/NotificationBadge/
└── Default.cshtml # [MODIFY] 重写标记:包装为 li#notification-bar + lpx-context-menu 下拉面板(标题/关闭、日期分组容器、底部跳转按钮);脚本增加 fetchLatest() 与日期分组渲染,并接入现有轮询/清理逻辑。
└── NotificationBadgeViewComponent.cs # [不变] 仅返回 Default.cshtml,无需修改。
沿用 ABP LeptonX 主题的通知下拉(lpx-context-menu)视觉规范,保持与现有后台框架一致的现代、简洁、悬浮卡片风格。面板为右上角悬浮的白色/主题色圆角卡片,带轻微阴影与边框,与顶部工具栏铃铛联动展开/收起。
lpx-badge(如“2 NEW”),右侧关闭图标(data-lpx-close,点击收起面板),与铃铛徽章未读数联动。lpx-menu-item-title 分区标题与 lpx-notification-items 列表;每条约 56px 高,左侧 bi-bell-fill 圆形成员图标,右侧 Title(高亮加粗)+ Content(截断单行)+ 时间小字;未读项带左侧色条/背景高亮。lpx-button),点击跳转 /notification/private-messages 查看完整私信。It already got code as below, it is a component view here:.Web\Components\Toolbar\NotificationBadge\Default.cshtml
<li class="outer-menu-item" id="notification-bar"> <a href="javascript:;" class="lpx-menu-item-link" data-lpx-ctx-toggle="notification-bar"> <span class="lpx-menu-item-icon" style="position:relative;"> <i class="lpx-icon action-icon bi bi-bell-fill" aria-hidden="true"></i> <small class="menu-item-badge" id="UnreadCountBadge" data-count="0" style="opacity:0;visibility:hidden;">0</small> </span> </a>
<div class="lpx-context-menu" data-lpx-context-menu="notification-bar">
<ul class="lpx-nav-menu-notification" id="notification-menu">
<li class="outer-menu-item" id="notification-header">
<a class="lpx-menu-item-link lpx-menu-item">
<span class="lpx-menu-item-icon">
<i class="lpx-icon outer-icon bi bi-bell-fill" aria-hidden="true"></i>
</span>
<span class="lpx-menu-item-text">Notification
<span class="lpx-badge" id="NotificationNewBadge" data-count="0" style="opacity:0;visibility:hidden;">0 NEW</span>
</span>
<span data-lpx-close="notification-bar">
<i class="lpx-icon bi bi-x outer-icon dd-icon" aria-hidden="true"></i>
</span>
</a>
</li>
</ul>
<div class="lpx-button-container" id="notification-footer">
<button class="lpx-button notif-btn-outline" id="MarkAllAsReadBtn" type="button">Mark all as read</button>
<a class="lpx-button notif-btn-primary" href="/notification/private-messages">See All Notifications</a>
</div>
</div>
</li>
<script> (function() { 'use strict';
// Clean up previous instance (e.g., after SPA re-render)
if (window.__notificationPollTimer) {
clearInterval(window.__notificationPollTimer);
window.__notificationPollTimer = null;
}
if (window.__notificationDomHandler) {
try { abp.event.off('abp.domUpdated', window.__notificationDomHandler); } catch (e) {}
window.__notificationDomHandler = null;
}
if (window.__notificationClickHandler) {
document.removeEventListener('click', window.__notificationClickHandler);
window.__notificationClickHandler = null;
}
var currentUnread = 0;
// Scoped lookup: avoid stale duplicate-ID elements from previous SPA renders.
function getBadge() {
var bar = document.getElementById('notification-bar');
return bar ? bar.querySelector('.menu-item-badge') : null;
}
function getPanel() {
var bar = document.getElementById('notification-bar');
return bar ? bar.querySelector('.lpx-context-menu') : null;
}
function isPanelOpen() {
var p = getPanel();
return !!(p && p.classList.contains('show'));
}
function unwrap(response) {
if (response && typeof response === 'object' && 'result' in response) return response.result;
return response;
}
function esc(s) {
return String(s == null ? '' : s).replace(/[&<>"']/g, function(c) {
return { '&': '&', '<': '&lt;', '>': '>', '"': '"', "'": ''' }[c];
});
}
// Use data-count attribute (CSS-driven visibility) instead of display
// manipulation so LeptonX's DOM watcher won't revert our changes.
function updateBadge(count) {
var num = parseInt(count, 10) || 0;
currentUnread = num;
// jQuery lookups — ABP is jQuery-based; avoids stale vanilla references
var $badge = $('#notification-bar .menu-item-badge');
if ($badge.length) {
$badge.attr('data-count', num)
.text(num > 99 ? '99+' : String(num));
}
var $newBadge = $('#NotificationNewBadge');
if ($newBadge.length) {
$newBadge.attr('data-count', num > 0 ? num : 0)
.text(num > 0 ? num + ' NEW' : '0 NEW');
}
}
function startOfDay(d) { return new Date(d.getFullYear(), d.getMonth(), d.getDate()); }
function groupLabel(date) {
var today = startOfDay(new Date());
var yest = new Date(today);
yest.setDate(today.getDate() - 1);
if (date >= today) return 'TODAY';
if (date >= yest) return 'YESTERDAY';
var dd = String(date.getDate()).padStart(2, '0');
var mm = String(date.getMonth() + 1).padStart(2, '0');
return dd + '.' + mm + '.' + date.getFullYear();
}
function formatTime(date) {
var hh = String(date.getHours()).padStart(2, '0');
var mm = String(date.getMinutes()).padStart(2, '0');
var today = startOfDay(new Date());
var yest = new Date(today);
yest.setDate(today.getDate() - 1);
if (date >= today) return hh + ':' + mm;
if (date >= yest) return 'Yesterday ' + hh + ':' + mm;
var dd = String(date.getDate()).padStart(2, '0');
var mm2 = String(date.getMonth() + 1).padStart(2, '0');
return mm2 + '/' + dd + ' ' + hh + ':' + mm;
}
function renderGroups(items) {
var menu = document.getElementById('notification-menu');
if (!menu) return;
var old = menu.querySelectorAll('.notif-group');
for (var i = 0; i < old.length; i++) old[i].remove();
if (!items || !items.length) {
var emptyLi = document.createElement('li');
emptyLi.className = 'outer-menu-item notif-group';
emptyLi.innerHTML = '<div class="lpx-notification-empty">暂无通知</div>';
menu.appendChild(emptyLi);
return;
}
var groups = [];
items.forEach(function(it, idx) {
var d = new Date(it.creationTime);
var label = groupLabel(d);
var g = null;
for (var j = 0; j < groups.length; j++) {
if (groups[j].label === label) { g = groups[j]; break; }
}
if (!g) { g = { label: label, items: [] }; groups.push(g); }
g.items.push({ data: it, unread: idx < currentUnread, date: d });
});
groups.forEach(function(g) {
var li = document.createElement('li');
li.className = 'outer-menu-item notif-group';
var html = '<div class="lpx-menu-item-title">' + esc(g.label) + '</div>'
+ '<ul class="lpx-notification-items lpx-inner-menu">';
g.items.forEach(function(it) {
html += '<li class="lpx-notification-item' + (it.unread ? ' unread' : '') + '" data-id="' + esc(it.data.id) + '">'
+ '<a class="lpx-notification-item-link">'
+ '<div class="lpx-notification-member-container"><i class="lpx-notification-member-icon bi bi-bell-fill"></i></div>'
+ '<div><p class="lpx-notification-text"><span class="lpx-notification-text-highlight">' + esc(it.data.title)
+ '</span> ' + esc(it.data.content) + '</p>'
+ '<small class="lpx-notification-text-small">' + esc(formatTime(it.date)) + '</small></div>'
+ '</a></li>';
});
html += '</ul>';
li.innerHTML = html;
menu.appendChild(li);
});
}
function fetchLatest() {
if (typeof abp === 'undefined' || !abp || !abp.ajax) return;
abp.ajax({
url: (abp.appPath || '') + 'api/notification/private-message?maxResultCount=5&sorting=CreationTime%20DESC',
type: 'GET',
success: function(response) {
var data = unwrap(response);
var items = (data && data.items) ? data.items : [];
renderGroups(items);
},
error: function() {}
});
}
function fetchCount() {
if (typeof abp === 'undefined' || !abp || !abp.ajax) return;
abp.ajax({
url: (abp.appPath || '') + 'api/notification/private-message/unread-count',
type: 'GET',
success: function(response) {
var num = parseInt(unwrap(response), 10) || 0;
updateBadge(num);
if (isPanelOpen()) fetchLatest();
},
error: function() {}
});
}
function markOneRead(id, liEl) {
if (typeof abp === 'undefined' || !abp || !abp.ajax) return;
abp.ajax({
url: (abp.appPath || '') + 'api/notification/private-message/' + id + '/mark-as-read',
type: 'POST',
success: function() {
if (liEl) liEl.classList.remove('unread');
updateBadge(Math.max(0, currentUnread - 1));
},
error: function() {}
});
}
function markAllRead() {
if (typeof abp === 'undefined' || !abp || !abp.ajax) return;
abp.ajax({
url: (abp.appPath || '') + 'api/notification/private-message/mark-all-as-read',
type: 'POST',
success: function() {
var menu = document.getElementById('notification-menu');
if (menu) {
var unread = menu.querySelectorAll('.lpx-notification-item.unread');
for (var i = 0; i < unread.length; i++) unread[i].classList.remove('unread');
}
updateBadge(0);
},
error: function() {}
});
}
function startPolling() {
if (window.__notificationPollTimer) return;
fetchCount();
window.__notificationPollTimer = setInterval(fetchCount, 30000);
}
window.refreshNotificationBadge = fetchCount;
window.refreshNotificationList = fetchLatest;
// Event delegation (survives SPA re-renders)
window.__notificationClickHandler = function(e) {
if (!e.target || !e.target.closest) return;
if (e.target.closest('[data-lpx-ctx-toggle="notification-bar"]')) {
fetchLatest();
return;
}
if (e.target.closest('#MarkAllAsReadBtn')) {
markAllRead();
return;
}
var itemEl = e.target.closest('.lpx-notification-item');
if (itemEl && itemEl.getAttribute('data-id')) {
markOneRead(itemEl.getAttribute('data-id'), itemEl);
}
};
document.addEventListener('click', window.__notificationClickHandler);
function tryInit() {
if (typeof abp === 'undefined' || !abp || !abp.ajax) return false;
window.__notificationDomHandler = fetchCount;
abp.event.on('abp.domUpdated', window.__notificationDomHandler);
startPolling();
return true;
}
if (!tryInit()) {
var attempts = 0;
var readyTimer = setInterval(function() {
attempts++;
if (tryInit()) {
clearInterval(readyTimer);
} else if (attempts > 40) {
clearInterval(readyTimer);
}
}, 500);
}
})(); </script>
Virtaul DOM generated, but cannot update the real DOM
ABP ver 9.3.5 with micro-services architecture, the UserFriendlyException not shown on the razor page client when backend API throw a UserFriendlyException, below is the code section:
A BusinessException threw but it cannot shown on the client side in a application service like below:
`
public virtual async Task
if (!result)
{
throw new InvalidVerificationCodeException();
}
var identityUser = await _phoneNumberLoginNewUserCreator.CreateAsync(input.PhoneNumber, input.UserName, input.Password, input.EmailAddress);
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(identityUser);
}
`
the InvalidVerificationCodeException is a BusinessException
I added an UserFriendlyException in the Controller like below:
`
[HttpPost]
[Route("register/by-phone-number")]
public virtual async Task
return result;
}
catch (BusinessException ex)
{
throw new UserFriendlyException(ex.Code);
}
}
`
it got below logs in the backend:
`
2025-10-08 17:38:45.887 +08:00 [WRN] ---------- RemoteServiceErrorInfo ----------
{ "code": null, "message": "EasyAbp.Abp.PhoneNumberLogin:InvalidVerificationCode", "details": null, "data": {}, "validationErrors": null }
2025-10-08 17:38:45.887 +08:00 [WRN] EasyAbp.Abp.PhoneNumberLogin:InvalidVerificationCode Volo.Abp.UserFriendlyException: EasyAbp.Abp.PhoneNumberLogin:InvalidVerificationCode at EasyAbp.Abp.PhoneNumberLogin.Web.Controllers.PhoneNumberLogin.Account.LoginController.RegisterByPhoneNumberAsync(RegisterWithPhoneNumberInput input) at lambda_method3691(Closure, Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.
then the client get a 403 forbidden HTTP Status code with the errors like below, it doesn't use UI throw a message:
{ "error": { "code": null, "message": "EasyAbp.Abp.PhoneNumberLogin:InvalidVerificationCode", "details": null, "data": {}, "validationErrors": null } }
2025-09-28 05:01:50.206 +08:00 [FTL] Host terminated unexpectedly! Volo.Abp.AbpInitializationException: An error occurred during the initialize Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor phase of the module Volo.Abp.AuditLogging.AbpAuditLoggingApplicationModule, Volo.Abp.AuditLogging.Application, Version=9.3.4.0, Culture=neutral, PublicKeyToken=null: Unexpected end of expression.. See the inner exception for details. ---> System.FormatException: Unexpected end of expression. at Quartz.CronExpression.BuildExpression(String expression) at Quartz.CronExpression..ctor(String cronExpression) at Quartz.CronExpression.ValidateExpression(String cronExpression) at Quartz.CronScheduleBuilder.CronSchedule(String cronExpression) at Quartz.CronScheduleTriggerBuilderExtensions.WithCronSchedule(TriggerBuilder triggerBuilder, String cronExpression) at Volo.Abp.BackgroundWorkers.Quartz.QuartzPeriodicBackgroundWorkerAdapter1.BuildWorker(IBackgroundWorker worker)
at Volo.Abp.BackgroundWorkers.Quartz.QuartzBackgroundWorkerManager.ReScheduleJobAsync(IBackgroundWorker worker, CancellationToken cancellationToken)
at Volo.Abp.BackgroundWorkers.Quartz.QuartzBackgroundWorkerManager.AddAsync(IBackgroundWorker worker, CancellationToken cancellationToken)
at Volo.Abp.AuditLogging.AbpAuditLoggingApplicationModule.OnApplicationInitializationAsync(ApplicationInitializationContext context)
at Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor.InitializeAsync(ApplicationInitializationContext context, IAbpModule module)
at Volo.Abp.Modularity.ModuleManager.InitializeModulesAsync(ApplicationInitializationContext context)
--- End of inner exception stack trace ---
at Volo.Abp.Modularity.ModuleManager.InitializeModulesAsync(ApplicationInitializationContext context)
at Volo.Abp.AbpApplicationBase.InitializeModulesAsync()
at Volo.Abp.AbpApplicationWithExternalServiceProvider.InitializeAsync(IServiceProvider serviceProvider)
at Microsoft.AspNetCore.Builder.AbpApplicationBuilderExtensions.InitializeApplicationAsync(IApplicationBuilder app)
at Viewtance.FM.Program.Main(String[] args) in D:\Source\Repos\apps\Viewtance.FM\src\Viewtance.FM.HttpApi.Host\Program.cs:line 58
`any miss configuration for integration service, or the generate proxy action is wrong?
I want to implement some actions (such as given award points to a user daily if the user sign in every day), I need to add an event to OpenIddict server event that it could fire an event handler to implement the logistics, I have followed the article add the event handler and registered in AuthServer project (a micro-services architecture solution), but the event handler not fired and no logs logged, is there any suggestions to debug, or I am using an incorrect way to configure the event handler?
public class DailyPointsHandler : IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>//, ITransientDependency
{
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ProcessSignInContext>()
.UseScopedHandler<DailyPointsHandler>()
.SetOrder(100_000)
.SetType(OpenIddictServerHandlerType.Custom)
.Build();
private readonly IdentityUserManager _userManager;
private readonly IClock _clock;
private readonly ILogger<DailyPointsHandler> _logger;
private readonly IRewardPointsHistoriesAppService _rewardPointsHistoriesAppService;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public DailyPointsHandler(
IdentityUserManager userManager,
IClock clock,
ILogger<DailyPointsHandler> logger,
IRewardPointsHistoriesAppService rewardPointsHistoriesAppService,
IUnitOfWorkManager unitOfWorkManager)
{
_userManager = userManager;
_clock = clock;
_logger = logger;
_rewardPointsHistoriesAppService = rewardPointsHistoriesAppService;
_unitOfWorkManager = unitOfWorkManager;
_logger.LogInformation("DailyPointsHandler constructor initialized");
}
public async ValueTask HandleAsync(OpenIddictServerEvents.ProcessSignInContext context)
{
_logger.LogInformation("进入每日积分处理器");
if (context is null) throw new ArgumentNullException(nameof(context));
// 跳过客户端凭证流程和刷新令牌流程
if (context.Request.IsClientCredentialsGrantType() ||
context.Request.IsRefreshTokenGrantType())
{
_logger.LogInformation("跳过非用户登录流程");
return;
}
// 获取用户ID
var userId = context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value;
if (string.IsNullOrEmpty(userId))
{
_logger.LogWarning("无法从声明中获取用户ID");
return;
}
try
{
using var uow = _unitOfWorkManager.Begin(requiresNew: true);
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
_logger.LogWarning("用户未找到: {UserId}", userId);
return;
}
if (user != null)
{
var rewardPointsHistoryCreate = new RewardPointsHistoryCreateDto();
rewardPointsHistoryCreate.UserId = user.Id;
rewardPointsHistoryCreate.RewardPointType = RewardPointType.DailySignIn;
await _rewardPointsHistoriesAppService.CreateAsync(rewardPointsHistoryCreate);
await uow.CompleteAsync();
_logger.LogInformation("用户 {UserName} 获得每日登录奖励", user.UserName);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "每日积分赠送处理失败");
// 失败时继续登录流程,不影响认证
}
}
}
registered it at:
private void PreConfigureOpenIddict(IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
{
PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddValidation(options =>
{
options.AddAudiences("AuthServer");
options.UseLocalServer();
options.UseAspNetCore();
});
builder.AddServer(options =>
{
options.AddEventHandler<ProcessSignInContext>(builder =>
builder.UseInlineHandler(context =>
{
// Attach custom metadata to the configuration document.
//context.Metadata["custom_metadata"] = 42;
context.Logger.LogInformation("Processing sign-in event in inline handler for user {userId}.", context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value);
return default;
}));
});
});
PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
{
serverBuilder.AddEventHandler(DailyPointsHandler.Descriptor);
serverBuilder.AddEventHandler(SignOutEventHandler.Descriptor);
serverBuilder.AddEventHandler<ProcessSignInContext>(builder =>
builder.UseInlineHandler(context =>
{
// Attach custom metadata to the configuration document.
//context.Metadata["custom_metadata"] = 42;
context.Logger.LogInformation("Processing sign-in event in inline handler for user {userId}.", context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value);
return default;
}));
});
}
Exception message and full stack trace: Navigation menu does not appear on specified language setting
Steps to reproduce the issue:
1 login with an account, back to the web
2 the navigation menus doesn't appear
3 if access the url directly then it will jump to the account login page let you login again
4 if change the language to another one, the navigation appears, if changed the language back the navigation menu disappeared again
5 if waiting for a moments(about 10 minutes around), the navigation menu may be appears
I have tried restart the application and the server, cleared the redis server cache, it cannot resolve it. I have 3 languages configured, english, zh-hant, zh-hans, the issue occurred on zh-hans.
Microsoft.AspNetCore.Authentication.AuthenticationFailureException: An error was encountered while handling the remote login. ---> Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_grant', error_description: 'The specified token is invalid.', error_uri: 'https://documentation.openiddict.com/errors/ID2004'. at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest) at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync() --- End of inner exception stack trace --- at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync() at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Prometheus.HttpMetrics.HttpRequestDurationMiddleware.Invoke(HttpContext context) at Prometheus.HttpMetrics.HttpRequestCountMiddleware.Invoke(HttpContext context) at Prometheus.HttpMetrics.HttpInProgressMiddleware.Invoke(HttpContext context) at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<
With Abp 9.2.1, abp suite 9.2.1
2025-07-13 04:57:07.493 +08:00 [INF] 1/10 - EntityGenerateCommand started... 2025-07-13 04:57:07.948 +08:00 [INF] 1/10 - EntityGenerateCommand completed. | Duration: 454 ms. 2025-07-13 04:57:07.948 +08:00 [INF] 2/10 - RepositoryCommand started... 2025-07-13 04:57:08.740 +08:00 [INF] 2/10 - RepositoryCommand completed. | Duration: 791 ms. 2025-07-13 04:57:08.740 +08:00 [INF] 3/10 - ManagerCommand started... 2025-07-13 04:57:08.988 +08:00 [INF] 3/10 - ManagerCommand completed. | Duration: 247 ms. 2025-07-13 04:57:08.988 +08:00 [INF] 4/10 - AppServiceCommand started... 2025-07-13 04:57:13.792 +08:00 [INF] 4/10 - AppServiceCommand completed. | Duration: 4804 ms. 2025-07-13 04:57:13.792 +08:00 [INF] 5/10 - PermissionCommand started... 2025-07-13 04:57:13.849 +08:00 [INF] 5/10 - PermissionCommand completed. | Duration: 56 ms. 2025-07-13 04:57:13.849 +08:00 [INF] 6/10 - ApplicationObjectMappingCommand started... 2025-07-13 04:57:13.878 +08:00 [ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "An internal error occurred during your request!", "details": null, "data": null, "validationErrors": null }
2025-07-13 04:57:13.879 +08:00 [ERR] Value cannot be null. (Parameter 'path')
System.ArgumentNullException: Value cannot be null. (Parameter 'path')
at System.ArgumentNullException.Throw(String paramName)
at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
at System.ArgumentException.ThrowNullOrEmptyException(String argument, String paramName)
at System.IO.File.ReadAllTextAsync(String path, CancellationToken cancellationToken)
at Volo.Abp.Suite.Areas.AbpSuite.CrudPageGenerator.Commands.ApplicationObjectMappingCommand.IJBgcTmZJf()
at Volo.Abp.Suite.Areas.AbpSuite.CrudPageGenerator.Commands.ApplicationObjectMappingCommand.ExecuteAsync(CrudPageCommandOptions options)
at Volo.Abp.Suite.Areas.AbpSuite.CrudPageGenerator.CommandManager.ExecuteAllAsync(CrudPageCommandOptions options)
at Volo.Abp.Suite.Areas.AbpSuite.CrudPageGenerator.Commands.CrudPageGenerator.GenerateAsync(EntityModel entity, Solution solution, EntityModel masterEntity, List1 navigationConnections) at Volo.Abp.Suite.Controllers.CrudPageGeneratorController.SaveAndGenerateEntityAsync(Guid solutionId, EntityModel entity) at lambda_method2003(Closure, Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
2025-07-13 04:57:13.884 +08:00 [INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'.
2025-07-13 04:57:13.885 +08:00 [INF] Executed action Volo.Abp.Suite.Controllers.CrudPageGeneratorController.SaveAndGenerateEntityAsync (Volo.Abp.Suite) in 62760.4142ms
2025-07-13 04:57:13.885 +08:00 [INF] Executed endpoint 'Volo.Abp.Suite.Controllers.CrudPageGeneratorController.SaveAndGenerateEntityAsync (Volo.Abp.Suite)'
2025-07-13 04:57:13.885 +08:00 [INF] Request finished HTTP/1.1 POST http://localhost:3000/api/abpSuite/crudPageGenerator/6f93a03f-284a-4842-ae53-00aec0831ca6/save-and-generate-entity - 500 null application/json; charset=utf-8 62761.8723ms
I have tried restart the application and the server, cleared the redis server cache, it cannot resolve it. I have 3 languages configured, english, zh-hant, zh-hans, the issue occurred on zh-hans.