I've done some more tests, I've narrowed the issue down to the theme. We're using the Lepton theme, not LeptonX.
v8.2.2 with LeptonX the chat toolbar icon correctly shows the unread count. v9.1.1 with Lepton the chat toolbar icon does not.
I hadn't mentioned this previously, cause honestly I had forgotten we weren't using, what is now, the default theme; but also wasn't expecting this to be the issue.
The js for adding the unread message count badge would appear to rely on an element with id "lpx-toolbar". In lepton the equivalent element id is "navbarToolbar".
I've "fixed"' the issue by adding this as the id for the li element containing the icon. But if you are on the chat page (and only this page) this completely throws out the alignment of the icon, so I'm only doing this when not on the chat page, which works fine since on this page the 'unread message count' badge is not shown.
$(function () {
if (window.location.pathname !== "/Chat") {
$('#navbarToolbar ul.navbar-nav li:has(a[href="/Chat"])').attr('id', 'lpx-toolbar');
}
});
This is obviously a bit of a hack but not sure there's an alternative, if you can suggest a better fix please let me know.
This is probably quite a niche problem but encase it helps anyone else I also added some css as the badge doesn't align nicely.
.lpx-menu-item-link .unread-message {
top: 2px;
right: 0px !important;
}
As a side note I've observed that (in v9.1.1 with Lepton X) the unread message count will be added dynamically if you previously had no unread messages, but does not subsequently get updated if the count increases. Not sure if this is by design, but is not what I was anticipating.
Sorry for being late.
Could you share the video and project again? thanks.
I've resent the video (https://we.tl/t-ImQtxQeUTS).
Sorry I no longer have the solution. If it would be helpful let me know and I can find time to recreate it.
Much appreciated, thank you
I've sent you a video following the repro steps with the issue occurring. https://we.tl/t-Ek8Ek1OI2r
If you can't reproduce feel free to close, or you can close either way, don't think there's much more I can contribute.
I'll be working round the issue by ensuring a description is set.
Hi, thank you for the quick response.
Yes this resolves the issue.
I understand why this is a logical constraint under normal circumstances, but for our use case it would very useful if this weren't the case.
I don't have access to the source code for the pro modules, am I right in assuming this check is performed in the TenantAppService, where I can see the AbpDbConnectionOptions being injected?
If I call the PUT after inserting the connection string directly in the database then it clears it, leaving me only the default one
Your email provider has rejected my email, tried with both .zip and .7z
Please let me know if there is some other way I can drop it to you or if the steps above are sufficient
Reproduction steps:
public class TestFeatureDefinitionProvider : FeatureDefinitionProvider
{
public override void Define(IFeatureDefinitionContext context)
{
var myGroup = context.AddGroup("Test Features");
var feature = myGroup.AddFeature(
name: "Test feature 1",
defaultValue: "true",
displayName: new FixedLocalizableString("Test feature 1"),
description: null,
valueType: new ToggleStringValueType()
);
var feature2 = feature.CreateChild(
name: "Test feature 2",
defaultValue: "true",
displayName: new FixedLocalizableString("Test feature 2"),
description: null,
valueType: new ToggleStringValueType()
);
var feature3 = myGroup.AddFeature(
name: "Test feature 3",
defaultValue: "true",
displayName: new FixedLocalizableString("Test feature 3"),
description: null,
valueType: new ToggleStringValueType()
);
}
}
Important part here is a null description. 3. Ran the application. 4. Logged in, confirmed the feature management modal worked. 5. Stopped the application. 6. Set FeatureManagementOptions.IsDynamicFeatureStoreEnabled to true in ConfigureService of web module. Commented out FeatureDefinitionProvider I had added (to simulate a feature seeded by another application). 7. Ran the application. 8. Logged in, went to feature management (for host, tenant, and edition) and modal fails to load with an error dialog.
Error in logs:
2025-03-27 17:53:21.044 +00:00 [ERR] Value cannot be null. (Parameter 'name')
System.ArgumentNullException: Value cannot be null. (Parameter 'name')
at System.ArgumentNullException.Throw(String paramName)
at Microsoft.Extensions.Localization.LocalizedString..ctor(String name, String value, Boolean resourceNotFound, String searchedLocation)
at Microsoft.Extensions.Localization.LocalizedString..ctor(String name, String value)
at Volo.Abp.Localization.FixedLocalizableString.Localize(IStringLocalizerFactory stringLocalizerFactory)
at Volo.Abp.FeatureManagement.FeatureAppService.CreateFeatureDto(FeatureNameValueWithGrantedProvider featureNameValueWithGrantedProvider, FeatureDefinition featureDefinition)
at Volo.Abp.FeatureManagement.FeatureAppService.GetAsync(String providerName, String providerKey)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, AbpAuditingOptions options, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope)
at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement.FeatureManagementModal.OnGetAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
I will email you my solution as well, but above is all I did.
My issue was specific to features that came from the dynamic store, so it can't be in the static store (i.e. no FeatureDefinitionProvider containing the feature in the application that is displaying the features).
I was also viewing the features for a tenant, I didn't verify the behaviour was the same from any of the other feature management screens, but from what I've seen there's nothing to suggest this would make a difference.
If your feature wasn't available statically, and so is definitely coming from the dynamic store, then I can try and make the time and create a minimally reproducible sample if you would like; but if this would not be a priority regardless of reproducibility then feel free to just re-close this, since the workaround for what I am observing is to just add a description this is what I have done and therefore it's no longer a very pressing issue.