Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.
- ABP Framework version: v4.0
- UI type: MVC
- DB provider: EF Core
- Tiered (MVC) or Identity Server Seperated (Angular): yes
- Exception message and stack trace:
- Steps to reproduce the issue:
- I am trying to create a connection string resolver. i think inheriting the default one would solve my problem as i dont want to change the logic, i just need to decrypt an encrypted string. where would i implement this? do you have a good sample for me to look at?
19 Answer(s)
-
0
Hi,
Just an example:
[Dependency(ReplaceServices = true)] public class MyConnectionStringResolver : MultiTenantConnectionStringResolver { private readonly IStringEncryptionService _encryptionService; public MyConnectionStringResolver( IOptionsSnapshot<AbpDbConnectionOptions> options, ICurrentTenant currentTenant, IServiceProvider serviceProvider, IStringEncryptionService encryptionService) : base(options, currentTenant, serviceProvider) { _encryptionService = encryptionService; } public override string Resolve(string connectionStringName = null) { var connectionString = base.Resolve(connectionStringName); return _encryptionService.Decrypt(connectionString); } }
-
0
This works fairly well, the one issuei am finding is that i sometimes get a null reference on this line, whcih makes no sense to me:
var connectionString = base.Resolve(connectionStringName);
-
0
If it is empty, you can return null directly without decrypt
-
0
i already do that, if the string being returned from the Base.resolver is empty i just return string.empty. should it be null instead? that being said, thats not the line that fails, i am getting the exception on the call to base.resolver trying to get the connection string so i can test its value.
-
0
Can I check it remotely? shiwei.liang@volosoft.com
-
0
i have no way to create the issue on demand, it just sort of happens some times, here is a screenshot of the code along with the error. not that it should matter, but the connectionStringName is not null, but null should be a valid option for it
https://gyazo.com/e1c07cce38a2e189cef5e7c4e4445639
-
0
Here is the whole error stack trace
" at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable
1.Enumerator.Dispose()\r\n at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable
1 source)\r\n at Castle.Proxies.Invocations.ITenantRepository_FindById.InvokeMethodOnTarget()\r\n at Castle.DynamicProxy.AbstractInvocation.Proceed()\r\n at Castle.DynamicProxy.AbstractInvocation.ProceedInfo.Invoke()\r\n at Castle.DynamicProxy.AsyncInterceptorBase.ProceedSynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.<ProceedAsync>d__7.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Volo.Abp.Uow.UnitOfWorkInterceptor.<InterceptAsync>d__3.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.<InterceptAsync>d__31.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Castle.DynamicProxy.NoCoverage.RethrowHelper.Rethrow(Exception exception)\r\n at Castle.DynamicProxy.NoCoverage.RethrowHelper.RethrowInnerIfAggregate(Exception exception)\r\n at Castle.DynamicProxy.AsyncInterceptorBase.InterceptSynchronousResult[TResult](AsyncInterceptorBase me, IInvocation invocation)\r\n at Castle.DynamicProxy.AbstractInvocation.Proceed()\r\n at Castle.Proxies.IBasicRepository
1Proxy_12.FindById(Guid id, Boolean includeDetails)\r\n at Volo.Saas.Tenants.TenantStore.Find(Guid id)\r\n at Volo.Abp.MultiTenancy.MultiTenantConnectionStringResolver.Resolve(String connectionStringName)\r\n at DAG.TFORM.Web.Resolvers.TFORMMultiTenantConnectionStringResolver.Resolve(String connectionStringName) in C:\Users\ronald.rizk\source\repos\tform_repo\DAG.TFORM\aspnet-core\src\DAG.TFORM.Web\Resolvers\TFORMMultiTenantConnectionStringResolver.cs:line 27"That line 27 is the line of code i identified above: var connectionString = base.Resolve(connectionStringName);
-
0
More information: i can repeat it fairly regularly when i am running multiple jobs simultaneously from hangfire.
hope that helps
-
0
Can you provide a simaple project to reproduce the problem?
-
0
our development cycle ends this coming week and i will have the time to put together the demo for that issue
-
0
we are having another resolver issue. when we tried to upgrade from 4.1.2 to 4.2.0 we started getting connection string issues. below is a screenshot of the error when we run. out connection string is encrypted. we have a resolver to decrypt it. it look to me as if there is somewhere we need to add a decryption somewhere that is not being covered by the resolver. thoughts?
-
0
I will check it out
-
0
Hi,
In 4.2.0 we started using asynchronous methods, try:
[Dependency(ReplaceServices = true)] public class MyConnectionStringResolver : MultiTenantConnectionStringResolver { private readonly IStringEncryptionService _encryptionService; public MyConnectionStringResolver( IOptionsSnapshot<AbpDbConnectionOptions> options, ICurrentTenant currentTenant, IServiceProvider serviceProvider, IStringEncryptionService encryptionService) : base(options, currentTenant, serviceProvider) { _encryptionService = encryptionService; } public override async Task<string> ResolveAsync(string connectionStringName = null) { var connectionString = await base.ResolveAsync(connectionStringName); return _encryptionService.Decrypt(connectionString); } }
-
0
no, that didnt solve it. i updated to 4.2.0, then i changed the resolved:
namespace DAG.TFORM.Web.Resolvers { [Dependency(ReplaceServices = true)] public class TFORMMultiTenantConnectionStringResolver : MultiTenantConnectionStringResolver { public TFORMMultiTenantConnectionStringResolver( IOptionsSnapshot<AbpDbConnectionOptions> options, ICurrentTenant currentTenant, IServiceProvider serviceProvider) : base(options, currentTenant, serviceProvider) { } public override async Task<string> ResolveAsync(string connectionStringName = null) { string connectionString = string.Empty; try { connectionString = await base.ResolveAsync(connectionStringName); } catch { return connectionString; } return string.IsNullOrEmpty(connectionString) ? connectionString : EncryptionHelper.Decrypt(connectionString); } } }
But when i try to runit i still get this error:
An unhandled exception occurred while processing the request. ArgumentException: Format of the initialization string does not conform to specification starting at index 0. System.Data.Common.DbConnectionOptions.GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string keyname, out string keyvalue)
ArgumentException: Format of the initialization string does not conform to specification starting at index 0. System.Data.Common.DbConnectionOptions.GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string keyname, out string keyvalue) System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary<string, string> parsetable, string connectionString, bool buildChain, Dictionary<string, string> synonyms, bool firstKey) System.Data.Common.DbConnectionOptions..ctor(string connectionString, Dictionary<string, string> synonyms, bool useOdbcRules) System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(string value) Npgsql.NpgsqlConnectionStringBuilder..ctor(string connectionString) Npgsql.NpgsqlConnection.GetPoolAndSettings() Npgsql.NpgsqlConnection.set_ConnectionString(string value) Npgsql.NpgsqlConnection..ctor(string connectionString) Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlRelationalConnection.CreateDbConnection() Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection() Microsoft.EntityFrameworkCore.Storage.RelationalCommand.CreateDbCommand(RelationalCommandParameterObject parameterObject, Guid commandId, DbCommandMethod commandMethod) Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable<T>+AsyncEnumerator.InitializeReaderAsync(DbContext _, bool result, CancellationToken cancellationToken) Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken) Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable<T>+AsyncEnumerator.MoveNextAsync() Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync<TSource>(IQueryable<TSource> source, CancellationToken cancellationToken) Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync<TSource>(IQueryable<TSource> source, CancellationToken cancellationToken) Volo.Abp.LanguageManagement.EntityFrameworkCore.EfCoreLanguageRepository.GetListAsync(bool isEnabled) Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo) Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue<TResult>.ProceedAsync() Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed) Volo.Abp.LanguageManagement.DatabaseLanguageProvider.MBFPd5o9y() Volo.Abp.Caching.DistributedCache<TCacheItem, TCacheKey>.GetOrAddAsync(TCacheKey key, Func<Task<TCacheItem>> factory, Func<DistributedCacheEntryOptions> optionsFactory, Nullable<bool> hideErrors, bool considerUow, CancellationToken token) Volo.Abp.LanguageManagement.DatabaseLanguageProvider.GetLanguagesAsync() Microsoft.AspNetCore.RequestLocalization.DefaultAbpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync() Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext() Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
-
0
Hi,
I can't reproduce the problem. Can you use the CLI to create a simple project to reproduce?
-
0
yes we did. so let me catch you up on what we did. we migrated to 4.2. we implemented the async resolvers. we also discovered that in 4.2 the connection string for postgres changed, so we fixed that issue. so the next provlem we are having is it is throwing errors on some of your conneciton string names that do not seem to go through the resolver.
from our log file: An exception occurred while iterating over the results of a query for context type 'Volo.Abp.LanguageManagement.EntityFrameworkCore.LanguageManagementDbContext'. System.ArgumentException: Keyword not supported: rn4ocm5xnxtsv7e0prkzlqmuhgvtophtqi7w1+a4eavhxhmt3kb4iimrdn5iienlrggqmluzbqb2r+f5gv6hqwoy1szdhtn1hnisqckb0mskgwanbruw/m9nb5q8twubtxhdl0qqvbnxofmclur89onez9hacgivfz2lsghlr+rzjvgzpdx0yv1ltgwhb3f9q2a/vaxahp02+6xhjrnudzbvihxlp776hn2il7p0vzq (Parameter 'keyword') at Npgsql.NpgsqlConnectionStringBuilder.GetProperty(String keyword) at Npgsql.NpgsqlConnectionStringBuilder.Remove(String keyword) at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value) at Npgsql.NpgsqlConnectionStringBuilder..ctor(String connectionString) at Npgsql.NpgsqlConnection.GetPoolAndSettings() at Npgsql.NpgsqlConnection.set_ConnectionString(String value) at Npgsql.NpgsqlConnection..ctor(String connectionString) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlRelationalConnection.CreateDbConnection() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection() at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.CreateDbCommand(RelationalCommandParameterObject parameterObject, Guid commandId, DbCommandMethod commandMethod) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable
1.Enumerator.InitializeReader(DbContext _, Boolean result) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func
3 operation, Func3 verifySucceeded) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable
1.Enumerator.MoveNext()the language management db context is somehow getting the encrypted connection string, not the decrypted version coming through the resolver. we also see this issue in the SaasDbContext as well. we are not implemnting a Saas connection string, it just grabs default, but how to we decrypt it in the pipeline of how you are getting it. i do have a project i can send you with code, the like is below:
-
0
is there a way to send the link privately? let me knwo if you need to the code or is my description is enough
-
0
Hi,
Can I check it remotely? shiwei.liang@volosoft.com
-
0
Override Resolve and resolveAsync methods