hi
Can you share the online URL of the authserver and API websites?
liming.ma@volosoft.com
hi
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.VirtualFileSystem;
namespace MyCompanyName.MyProjectName.Web;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IDynamicFileProvider))]
public class CachedBundleDynamicFileProvider : DictionaryBasedFileProvider, IDynamicFileProvider, ISingletonDependency
{
protected override IDictionary<string, IFileInfo> Files => DynamicFiles;
protected ConcurrentDictionary<string, IFileInfo> DynamicFiles { get; }
protected ConcurrentDictionary<string, ChangeTokenInfo> FilePathTokenLookup { get; }
protected IDistributedCache<InMemoryFileInfoCacheItem> Cache { get; }
protected IOptions<AbpBundlingOptions> BundlingOptions { get; }
public CachedBundleDynamicFileProvider(
IDistributedCache<InMemoryFileInfoCacheItem> cache,
IOptions<AbpBundlingOptions> bundlingOptions)
{
Cache = cache;
BundlingOptions = bundlingOptions;
FilePathTokenLookup = new ConcurrentDictionary<string, ChangeTokenInfo>(StringComparer.OrdinalIgnoreCase); ;
DynamicFiles = new ConcurrentDictionary<string, IFileInfo>();
}
public override IFileInfo GetFileInfo(string? subpath)
{
var fileInfo = base.GetFileInfo(subpath);
if (!subpath.IsNullOrWhiteSpace() && fileInfo is NotFoundFileInfo &&
subpath.Contains(BundlingOptions.Value.BundleFolderName, StringComparison.OrdinalIgnoreCase))
{
var filePath = NormalizePath(subpath);
var cacheItem = Cache.Get(filePath);
if (cacheItem == null)
{
return fileInfo;
}
fileInfo = new InMemoryFileInfo(filePath, cacheItem.FileContent, cacheItem.Name);
DynamicFiles.AddOrUpdate(filePath, fileInfo, (key, value) => fileInfo);
}
return fileInfo;
}
public void AddOrUpdate(IFileInfo fileInfo)
{
var filePath = fileInfo.GetVirtualOrPhysicalPathOrNull();
Cache.GetOrAdd(filePath!, () => new InMemoryFileInfoCacheItem(filePath!, fileInfo.ReadBytes(), fileInfo.Name));
DynamicFiles.AddOrUpdate(filePath!, fileInfo, (key, value) => fileInfo);
ReportChange(filePath!);
}
public bool Delete(string filePath)
{
Cache.Remove(filePath);
if (!DynamicFiles.TryRemove(filePath, out _))
{
return false;
}
ReportChange(filePath);
return true;
}
public override IChangeToken Watch(string filter)
{
return GetOrAddChangeToken(filter);
}
private IChangeToken GetOrAddChangeToken(string filePath)
{
if (!FilePathTokenLookup.TryGetValue(filePath, out var tokenInfo))
{
var cancellationTokenSource = new CancellationTokenSource();
var cancellationChangeToken = new CancellationChangeToken(cancellationTokenSource.Token);
tokenInfo = new ChangeTokenInfo(cancellationTokenSource, cancellationChangeToken);
tokenInfo = FilePathTokenLookup.GetOrAdd(filePath, tokenInfo);
}
return tokenInfo.ChangeToken;
}
private void ReportChange(string filePath)
{
if (FilePathTokenLookup.TryRemove(filePath, out var tokenInfo))
{
tokenInfo.TokenSource.Cancel();
}
}
protected struct ChangeTokenInfo
{
public ChangeTokenInfo(
CancellationTokenSource tokenSource,
CancellationChangeToken changeToken)
{
TokenSource = tokenSource;
ChangeToken = changeToken;
}
public CancellationTokenSource TokenSource { get; }
public CancellationChangeToken ChangeToken { get; }
}
}
[Serializable]
[IgnoreMultiTenancy]
public class InMemoryFileInfoCacheItem
{
public InMemoryFileInfoCacheItem(string dynamicPath, byte[] fileContent, string name)
{
DynamicPath = dynamicPath;
Name = name;
FileContent = fileContent;
}
public string DynamicPath { get; set; }
public string Name { get; set; }
public byte[] FileContent { get; set; }
}
hi
Try to configure AbpDbContextOptions as well.
Configure<AbpDbContextOptions>(options =>
{
/* The main point to change your DBMS.
* See also BookStoreMigrationsDbContextFactory for EF Core tooling. */
options.UseSqlServer(x => x.UseCompatibilityLevel(120));
});
hi
The Audit logs and Entity Changes are two concepts.
5 Edit the property "Title" of the record
Will create an audit log entity and won't create any Entity Changes entities.
hi
What's your email?
What lepton package version are you using right now?
Your code is no problem. but I think TopMenu not working in your project. so you can try to override the SideMenu to test it again.
@using Volo.Abp.DependencyInjection
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.Navigation
@inherits MobileNavbar
@attribute [ExposeServices(typeof(MobileNavbar))]
@attribute [Dependency(ReplaceServices = true)]
<strong>TestXXX</strong>
And have you configured the LeptonXThemeBlazorOptions?
Configure<LeptonXThemeBlazorOptions>(options =>
{
options.Layout = LeptonXBlazorLayouts.SideMenu or TopMenu;
});
hi
You can try to override the SideMenu to test it again.