Hi all,
I have an ApplicationService action that may raise a warning based on some conditions, which must abort and undo the current UOW, then return a warning to the user. The user then confirm the warning and re-submit the same request (with a flag confirmed:true so the warning isn't raised again).
The simplest way is to throw an UserFriendlyException, but then on the client I need to distinguish Error and Warning. My first idea is to extend the ABP framework with a UserFriendlyWarningException that I could throw and I could serialized it in a different way than the UserFriendlyException.
But before going through this, I was wondering how do you guys would handle this and if there is something already built-in for warning/confirmation like that.
Thanks !
I see very slow startup time with my ABP based app. This is caused mainly by TypeFinder.cs.
Please see my comment on this issue: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/pull/524">https://github.com/aspnetboilerplate/as ... e/pull/524</a>
Thanks.
I need to make an Application Service method that returns a list of users which have a specific Permission granted.
I'm injecting an IPermissionChecker in my app service.
When I try to call IPermissionChecker.IsGranted inside my LINQ query (before the SQL query is actually executed), I get an exception: System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean IsGranted(Abp.Authorization.IPermissionChecker, Int64, System.String)' method, and this method cannot be translated into a store expression.
ex:
var list = _userRepository.GetAll()
.Where(x => x.IsActive && !x.IsDeleted)
.Where(x => _permissionChecker.IsGranted(x.Id, PermissionNames.CanBeAssigneeOnTask))
.ToList();
So instead, I tried to first load all users into memory, then call IPermissionChecker.IsGranted() for each users.
foreach (AppUser appUser in list)
{
if (_permissionChecker.IsGranted(appUser.Id, PermissionNames.CanBeAssigneeOnTask))
{
...
}
}
That works but each calls to IPermissionChecker.IsGranted() issues SEVEN different sql queries (I'm monitoring with SQL Profiler). So if I have 100+ users * 7 queries = 700+ queries... it is getting very slow to execute.
Is there any way to optimize this ?
We have an ABP based application running on Azure Web App, with an Azure SQL Database.
Once every 2-3 days, I can see in my logs an exception related to distributed transaction. It is expected that DTC does not work on Azure, but I don't understand why a transaction is trying to be promoted to a distributed one.
All my database interactions are done through ABP UnitOFWork, using auto-implemented IRepository. I have a single DBContext.
I'm using NLog, configured using Castle LoggingFacility.UseNLog().
So I was wondering if someone else have experienced the same issue ?
I suspect that it may be related to NLog and DBContext connections. I will try to add "ENLIST=false;" to my NLog connection string to see if it helps.
Other suggestions where to look at ?
Here is the details of the exception. It occurs during the DBContext.SaveChanges().
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: The Promote method returned an invalid value for the distributed transaction. ---> System.ArgumentException: Value does not fall within the expected range.
at System.Transactions.Oletx.IDtcProxyShimFactory.ConnectToProxy(String nodeName, Guid resourceManagerIdentifier, IntPtr managedIdentifier, Boolean& nodeNameMatches, UInt32& whereaboutsSize, CoTaskMemHandle& whereaboutsBuffer, IResourceManagerShim& resourceManagerShim)
at System.Transactions.Oletx.DtcTransactionManager.Initialize()
at System.Transactions.Oletx.DtcTransactionManager.get_ProxyShimFactory()
at System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken)
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
--- End of inner exception stack trace ---
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)
at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.<Open>b__36(DbConnection t, DbConnectionInterceptionContext c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.EntityConnection.<Open>b__2()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation)
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
--- End of inner exception stack trace ---
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
at System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection(Boolean shouldMonitorTransactions)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at PMP.EntityFramework.PMPDbContext.SaveChanges() in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\PMP.EntityFramework\EntityFramework\PMPDbContext.cs:line 146
at Abp.EntityFramework.Repositories.EfRepositoryBase`3.InsertAndGetId(TEntity entity) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\Repositories\EfRepositoryBaseOfTEntityAndTPrimaryKey.cs:line 89
at Castle.Proxies.EfRepositoryBase`2Proxy_14.InsertAndGetId_callback(Project entity)
at Castle.Proxies.Invocations.EfRepositoryBase`3_InsertAndGetId_21.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 28
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.EfRepositoryBase`2Proxy_14.InsertAndGetId(Project entity)
at PMP.Project.Command.ImportProjectFromSap.Filters.CreateProjectIfNotExist.Execute(ImportProjectFromSapMessage msg) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\PMP.Application\Project\Command.ImportProjectFromSap\Filters\CreateProjectIfNotExist.cs:line 32
at Abp.FilterPipeline.Pipeline`1.<>c__DisplayClass1.<Execute>b__0(IFilter`1 f) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\Abp.Genisys\FilterPipeline\Pipeline.cs:line 14
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at Abp.FilterPipeline.Pipeline`1.Execute(T input) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\Abp.Genisys\FilterPipeline\Pipeline.cs:line 14
at Castle.Proxies.ImportProjectFromSapServiceProxy.Execute_callback(ImportProjectFromSapInput input)
at Castle.Proxies.Invocations.IImportProjectFromSapService_Execute.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Logging.LoggingInterceptor.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\Abp.Genisys\Logging\LoggingInterceptor.cs:line 32
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Auditing.AuditingInterceptor.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Auditing\AuditingInterceptor.cs:line 40
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Authorization.Interceptors.AuthorizationInterceptor.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Authorization\Interceptors\AuthorizationInterceptor.cs:line 32
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 60
at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformUow(IInvocation invocation, UnitOfWorkOptions options) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 52
at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 42
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Runtime.Validation.Interception.ValidationInterceptor.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp\Runtime\Validation\Interception\ValidationInterceptor.cs:line 21
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.ImportProjectFromSapServiceProxy.Execute(ImportProjectFromSapInput input)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Abp.WebApi.Controllers.Dynamic.Interceptors.AbpDynamicApiControllerInterceptor`1.Intercept(IInvocation invocation) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp.Web.Api\WebApi\Controllers\Dynamic\Interceptors\AbpDynamicApiControllerInterceptor.cs:line 44
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.DynamicApiController`1Proxy_41.Execute(ImportProjectFromSapInput input)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClassc.<GetExecutor>b__6(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at Abp.WebApi.Controllers.Dynamic.Selectors.DyanamicHttpActionDescriptor.<ExecuteAsync>b__0(Task`1 task) in c:\InformatiqueIndustrielleSG\BCH\src\PMP\src\trunk\libs\aspnetboilerplate\src\Abp.Web.Api\WebApi\Controllers\Dynamic\Selectors\DyanamicHttpActionDescriptor.cs:line 54
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
Is there a built-in ABP class that I can inject into my ApplicationService, to retrieve an absolute url of a page in my app ? I need to send an email containing an url to my app.
Thanks!