Activities of "LiSong"

Answer

sorry, had to create 3 posts, it was too long, so if you checked the screenshot, the types are correct. but still not working,

Answer

using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Tapp.EntityFrameworkCore; using Tapp.Localization; using Tapp.MultiTenancy; using Tapp.Permissions; using Tapp.Web.Menus; using Microsoft.OpenApi.Models; using Volo.Abp; using Volo.Abp.Studio; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.UI; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling; using Volo.Abp.LeptonX.Shared; using Volo.Abp.Autofac; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; using Volo.Abp.PermissionManagement; using Volo.Abp.PermissionManagement.Web; using Volo.Abp.UI.Navigation.Urls; using Volo.Abp.UI; using Volo.Abp.UI.Navigation; using Volo.Abp.VirtualFileSystem; using Volo.Abp.Identity.Web; using Volo.Abp.FeatureManagement; using OpenIddict.Server.AspNetCore; using OpenIddict.Validation.AspNetCore; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Commercial; using Tapp.Web.HealthChecks; using Volo.Abp.Account.Admin.Web; using Volo.Abp.Account.Public.Web; using Volo.Abp.Account.Public.Web.ExternalProviders; using Volo.Abp.Account.Pro.Public.Web.Shared; using Volo.Abp.AuditLogging.Web; using Volo.Abp.LanguageManagement; using Volo.Abp.TextTemplateManagement.Web; using Volo.Saas.Host; using Volo.Abp.Gdpr.Web; using Volo.Abp.Gdpr.Web.Extensions; using Volo.Abp.OpenIddict.Pro.Web; using System; using System.Security.Cryptography.X509Certificates; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Google; using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Authentication.Twitter; using Microsoft.AspNetCore.Extensions.DependencyInjection; using Volo.Abp.Account.Web; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Identity; using Volo.Abp.Swashbuckle; using Volo.Abp.OpenIddict; using Volo.Abp.Security.Claims; using Volo.Abp.SettingManagement.Web; using Volo.Abp.Studio.Client.AspNetCore; using Medallion.Threading; using StackExchange.Redis; using Medallion.Threading.Redis; using Volo.Abp.DistributedLocking;

namespace Tapp.Web;

[DependsOn( typeof(AbpDistributedLockingModule), typeof(TappHttpApiModule), typeof(TappApplicationModule), typeof(TappEntityFrameworkCoreModule), typeof(AbpAutofacModule), typeof(AbpStudioClientAspNetCoreModule), typeof(AbpIdentityWebModule), typeof(AbpAspNetCoreMvcUiLeptonXThemeModule), typeof(AbpAccountPublicWebOpenIddictModule), typeof(AbpAuditLoggingWebModule), typeof(SaasHostWebModule), typeof(AbpAccountAdminWebModule), typeof(AbpOpenIddictProWebModule), typeof(LanguageManagementWebModule), typeof(TextTemplateManagementWebModule), typeof(AbpGdprWebModule), typeof(AbpFeatureManagementWebModule), typeof(AbpSwashbuckleModule), typeof(AbpAspNetCoreSerilogModule) )] public class TappWebModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration();

    context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
    {
        options.AddAssemblyResource(
            typeof(TappResource),
            typeof(TappDomainModule).Assembly,
            typeof(TappDomainSharedModule).Assembly,
            typeof(TappApplicationModule).Assembly,
            typeof(TappApplicationContractsModule).Assembly,
            typeof(TappWebModule).Assembly
        );
    });

    PreConfigure<OpenIddictBuilder>(builder =>
    {
        builder.AddValidation(options =>
        {
            options.AddAudiences("Tapp");
            options.UseLocalServer();
            options.UseAspNetCore();
        });
    });

    if (!hostingEnvironment.IsDevelopment())
    {
        PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
        {
            options.AddDevelopmentEncryptionAndSigningCertificate = false;
        });

        PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
        {
            serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
            serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
        });
    }
}

public override void ConfigureServices(ServiceConfigurationContext context)
{
    var hostingEnvironment = context.Services.GetHostingEnvironment();
    var configuration = context.Services.GetConfiguration();

    if (!configuration.GetValue<bool>("App:DisablePII"))
    {
        Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
        Microsoft.IdentityModel.Logging.IdentityModelEventSource.LogCompleteSecurityArtifact = true;
    }

    if (!configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"))
    {
        Configure<OpenIddictServerAspNetCoreOptions>(options =>
        {
            options.DisableTransportSecurityRequirement = true;
        });
        
        Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
        });
    }

    context.Services.AddSingleton<IDistributedLockProvider>(sp =>
    {
        var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!);
        return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
    });

    ConfigureBundles();
    ConfigureUrls(configuration);
    ConfigurePages(configuration);
    ConfigureImpersonation(context, configuration);
    ConfigureHealthChecks(context);
    ConfigureExternalProviders(context);
    ConfigureCookieConsent(context);
    ConfigureAuthentication(context);
    ConfigureAutoMapper();
    ConfigureVirtualFileSystem(hostingEnvironment);
    ConfigureNavigationServices();
    ConfigureAutoApiControllers();
    ConfigureSwaggerServices(context.Services);
    ConfigureTheme();

    Configure<PermissionManagementOptions>(options =>
    {
        options.IsDynamicPermissionStoreEnabled = true;
    });
}

private void ConfigureCookieConsent(ServiceConfigurationContext context)
{
    context.Services.AddAbpCookieConsent(options =>
    {
        options.IsEnabled = true;
        options.CookiePolicyUrl = "/CookiePolicy";
        options.PrivacyPolicyUrl = "/PrivacyPolicy";
    });
}

private void ConfigureTheme()
{
    Configure<LeptonXThemeOptions>(options =>
    {
        options.DefaultStyle = LeptonXStyleNames.System;
    });

    Configure<LeptonXThemeMvcOptions>(options =>
    {
        options.ApplicationLayout = LeptonXMvcLayouts.SideMenu;
    });
}

private void ConfigureHealthChecks(ServiceConfigurationContext context)
{
    context.Services.AddTappHealthChecks();
}

private void ConfigureBundles()
{
    Configure<AbpBundlingOptions>(options =>
    {
        options.StyleBundles.Configure(
            LeptonXThemeBundles.Styles.Global,
            bundle =>
            {
                bundle.AddFiles("/global-scripts.js");
                bundle.AddFiles("/global-styles.css");
            }
        );
    });
}

private void ConfigurePages(IConfiguration configuration)
{
    Configure<RazorPagesOptions>(options =>
    {
        options.Conventions.AuthorizePage("/HostDashboard", TappPermissions.Dashboard.Host);
        options.Conventions.AuthorizePage("/TenantDashboard", TappPermissions.Dashboard.Tenant);
    });
}

private void ConfigureUrls(IConfiguration configuration)
{
    Configure<AppUrlOptions>(options =>
    {
        options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
    });
}

private void ConfigureAuthentication(ServiceConfigurationContext context)
{
    context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
    context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
    {
        options.IsDynamicClaimsEnabled = true;
    });
}

private void ConfigureImpersonation(ServiceConfigurationContext context, IConfiguration configuration)
{
    context.Services.Configure<AbpSaasHostWebOptions>(options =>
    {
        options.EnableTenantImpersonation = true;
    });
    context.Services.Configure<AbpIdentityWebOptions>(options =>
    {
        options.EnableUserImpersonation = true;
    });
    context.Services.Configure<AbpAccountOptions>(options =>
    {
        options.TenantAdminUserName = "admin";
        options.ImpersonationTenantPermission = SaasHostPermissions.Tenants.Impersonation;
        options.ImpersonationUserPermission = IdentityPermissions.Users.Impersonation;
    });
}

private void ConfigureAutoMapper()
{
    Configure<AbpAutoMapperOptions>(options =>
    {
        options.AddMaps<TappWebModule>();
    });
}

private void ConfigureVirtualFileSystem(IWebHostEnvironment hostingEnvironment)
{
    Configure<AbpVirtualFileSystemOptions>(options =>
    {
        options.FileSets.AddEmbedded<TappWebModule>();

        if (hostingEnvironment.IsDevelopment())
        {
            options.FileSets.ReplaceEmbeddedByPhysical<TappDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}Tapp.Domain.Shared", Path.DirectorySeparatorChar)));
            options.FileSets.ReplaceEmbeddedByPhysical<TappDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}Tapp.Domain", Path.DirectorySeparatorChar)));
            options.FileSets.ReplaceEmbeddedByPhysical<TappApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}Tapp.Application.Contracts", Path.DirectorySeparatorChar)));
            options.FileSets.ReplaceEmbeddedByPhysical<TappApplicationModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}Tapp.Application", Path.DirectorySeparatorChar)));
            options.FileSets.ReplaceEmbeddedByPhysical<TappHttpApiModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}Tapp.HttpApi", Path.DirectorySeparatorChar)));
            options.FileSets.ReplaceEmbeddedByPhysical<TappWebModule>(hostingEnvironment.ContentRootPath);
        }
    });
}

private void ConfigureNavigationServices()
{
    Configure<AbpNavigationOptions>(options =>
    {
        options.MenuContributors.Add(new TappMenuContributor());
    });

    Configure<AbpToolbarOptions>(options =>
    {
        options.Contributors.Add(new TappToolbarContributor());
    });
}

private void ConfigureAutoApiControllers()
{
    Configure<AbpAspNetCoreMvcOptions>(options =>
    {
        options.ConventionalControllers.Create(typeof(TappApplicationModule).Assembly);
    });
}

private void ConfigureSwaggerServices(IServiceCollection services)
{
    services.AddAbpSwaggerGen(
        options =>
        {
            options.SwaggerDoc("v1", new OpenApiInfo { Title = "Tapp API", Version = "v1" });
            options.DocInclusionPredicate((docName, description) => true);
            options.CustomSchemaIds(type => type.FullName);
        }
    );
}

private void ConfigureExternalProviders(ServiceConfigurationContext context)
{
    context.Services.AddAuthentication()
        .AddGoogle(GoogleDefaults.AuthenticationScheme, options =>
        {
            options.ClaimActions.MapJsonKey(AbpClaimTypes.Picture, "picture");
        })
        .WithDynamicOptions<GoogleOptions, GoogleHandler>(
            GoogleDefaults.AuthenticationScheme,
            options =>
            {
                options.WithProperty(x => x.ClientId);
                options.WithProperty(x => x.ClientSecret, isSecret: true);
            }
        )
        .AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, options =>
        {
            //Personal Microsoft accounts as an example.
            options.AuthorizationEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
            options.TokenEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";

            options.ClaimActions.MapCustomJson("picture", _ => "https://graph.microsoft.com/v1.0/me/photo/$value");
            options.SaveTokens = true;
        })
        .WithDynamicOptions<MicrosoftAccountOptions, MicrosoftAccountHandler>(
            MicrosoftAccountDefaults.AuthenticationScheme,
            options =>
            {
                options.WithProperty(x => x.ClientId);
                options.WithProperty(x => x.ClientSecret, isSecret: true);
            }
        )
        .AddTwitter(TwitterDefaults.AuthenticationScheme, options =>
        {
            options.ClaimActions.MapJsonKey(AbpClaimTypes.Picture,"profile_image_url_https");
            options.RetrieveUserDetails = true;
        })
        .WithDynamicOptions<TwitterOptions, TwitterHandler>(
            TwitterDefaults.AuthenticationScheme,
            options =>
            {
                options.WithProperty(x => x.ConsumerKey);
                options.WithProperty(x => x.ConsumerSecret, isSecret: true);
            }
        );
}


public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
    var app = context.GetApplicationBuilder();
    var env = context.GetEnvironment();

    app.UseForwardedHeaders();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseAbpRequestLocalization();

    if (!env.IsDevelopment())
    {
        app.UseErrorPage();
        app.UseHsts();
    }

    app.UseAbpCookieConsent();
    app.UseCorrelationId();
    app.MapAbpStaticAssets();
    app.UseAbpStudioLink();
    app.UseRouting();
    app.UseAbpSecurityHeaders();
    app.UseAuthentication();
    app.UseAbpOpenIddictValidation();

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

    app.UseUnitOfWork();
    app.UseDynamicClaims();
    app.UseAuthorization();
    app.UseSwagger();
    app.UseAbpSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "Tapp API");
    });
    app.UseAuditing();
    app.UseAbpSerilogEnrichers();
    app.UseConfiguredEndpoints();
}

}

Answer

still not working, pls take a look:

using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Threading.Tasks; using System; using Volo.Abp.DistributedLocking; using Medallion.Threading;

namespace Tapp.Web.Pages;

public class IndexModel : TappPageModel { private readonly IAbpDistributedLock _distributedLock; private readonly IDistributedLockProvider _distributedLockProvider; private readonly ILogger<IndexModel> _logger;

public IndexModel(IAbpDistributedLock distributedLock, IDistributedLockProvider distributedLockProvider, ILogger&lt;IndexModel&gt; logger)
{
    _distributedLock = distributedLock;
    _distributedLockProvider = distributedLockProvider;
    _logger = logger;
}

public string LockTestResult { get; set; }
public virtual async Task&lt;IActionResult&gt; OnGetAsync()
{
    await RunLockTestAsync();
    return Page();
}

private async Task RunLockTestAsync()
{
    var currentUserId = Guid.NewGuid(); // For testing, generate a dummy user id
    var lockKey = $"form-submission-lock:";
    for (int i = 0; i &lt; 3; i++)
    {
        await using var handle = await _distributedLock.TryAcquireAsync(lockKey, TimeSpan.FromSeconds(5));
        if (handle != null)
        {
            await DummyCriticalSection();
            _logger.LogInformation(&quot;Lock acquired and dummy section executed.&quot;);
            //return &quot;Lock acquired and dummy section executed.&quot;;
        }
        else
        {
            _logger.LogWarning(&quot;Could not acquire lock, retrying...&quot;);
        }

    }
    _logger.LogError(&quot;Could not acquire lock after 3 attempts.&quot;);
    //return &quot;Could not acquire lock after 3 attempts.&quot;;
}

private async Task DummyCriticalSection()
{
    await Task.Delay(1000); // Simulate work
}

}

<ItemGroup> <PackageReference Include="AspNetCore.HealthChecks.UI" Version="9.0.0" /> <PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0" /> <PackageReference Include="DistributedLock.Core" Version="1.0.8" /> <PackageReference Include="DistributedLock.Redis" Version="1.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.0" /> <PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="9.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="9.0.0" /> <PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="9.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="9.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Twitter" Version="9.0.0" /> <PackageReference Include="StackExchange.Redis" Version="2.8.58" /> <PackageReference Include="Volo.Abp.DistributedLocking" Version="9.0.4" /> </ItemGroup>

Answer

just sent you an email with the project thanks

Answer

I have set up the breakpoints, and I confirm

the Type of _distributedLock is MedallionAbpDistributedLock.

the IDistributedLockProvider is RedisDistributedSynchronizationProvider

but the lock still doesnt work

Answer

thanks I am checking

Answer

ok. thx

Answer

I don't see the code in the whole solution, I've actually searched for 'ConfigureCors' in the entire solution but found 0 matches, do I need to add the configurecors function myself? I want to clarify this to make sure I don't override anything underlying that might compromise security. thanks

Answer

sorry, I am using a layered application and non-Tiered, I was confused by layered and tiered. do you mind also checking the layered application for me. thanks

Answer

yes, it's a CORS error, I ran this command: curl -i -X OPTIONS https://localhost:44381/api/app/ethnicities -H 'Origin: http://localhost:5173' -H 'Access-Control-Request-Method: GET'

and got C:\Users\songh>curl -i -X OPTIONS https://localhost:44381/api/app/ethnicities -H "Origin: http://localhost:5173" -H "Access-Control-Request-Method: GET" HTTP/1.1 405 Method Not Allowed Transfer-Encoding: chunked Allow: GET, HEAD, POST Server: Microsoft-IIS/10.0 X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN X-Correlation-Id: 3880f62679854d47a73e1b5cff09a43c X-SourceFiles: =?UTF-8?B?RDpcZ2l0XHRhcHAtOVxzcmNcVGFwcC5XZWJcYXBpXGFwcFxldGhuaWNpdGllcw==?= Date: Tue, 08 Apr 2025 23:14:45 GMT

Showing 21 to 30 of 80 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.1.0-preview. Updated on December 10, 2025, 12:02
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.