- ABP Framework version: v4.3.R2
- UI type: MVC
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): no
- Exception message and stack trace:
- Steps to reproduce the issue:
Have created a new app and i don't seem to see the new module: forms as per pre release notes.
How can i review it ?
14 Answer(s)
-
0
Seen it. One has to add the package.
-
0
Am using ABP 5.2.1 - MVC
I have the below error when adding choice-based questions. The choices don't save to DB
[19:22:29 ERR] An error occurred while saving the entity changes. See the inner exception for details. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details. ---> Microsoft.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_FrmChoices_FrmQuestions_ChoosableQuestionId". The conflict occurred in database "SELFSERVICE", table "dbo.FrmChoices", column 'ChoosableQuestionId'. The statement has been terminated. at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result) at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location --- at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) ClientConnectionId:a846ae0b-c8a1-47df-b8c2-a9a86c85e45a Error Number:547,State:0,Class:16 --- End of inner exception stack trace --- at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Volo.Abp.EntityFrameworkCore.AbpDbContext`1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository`2.DeleteAsync(TEntity entity, Boolean autoSave, CancellationToken cancellationToken) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous(IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapter.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) at Volo.Abp.Domain.Repositories.RepositoryExtensions.HardDeleteWithUnitOfWorkAsync[TEntity](IBasicRepository`1 repository, TEntity entity, Boolean autoSave, CancellationToken cancellationToken, IUnitOfWork currentUow) at Volo.Abp.Domain.Repositories.RepositoryExtensions.HardDeleteAsync[TEntity](IBasicRepository`1 repository, TEntity entity, Boolean autoSave, CancellationToken cancellationToken) at Volo.Forms.Questions.QuestionManager.UpdateAsync(Guid id, String title, Int32 index, Boolean isRequired, String description, QuestionTypes questionType, Boolean hasOtherOption, List`1 choiceList) 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.Forms.Questions.QuestionAppService.UpdateAsync(Guid id, UpdateQuestionDto input) 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, 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.Features.FeatureInterceptor.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 lambda_method5045(Closure , Object ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) [19:22:29 INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'. [19:22:29 INF] Executed action Volo.Forms.Questions.QuestionController.UpdateAsync (Volo.Forms.HttpApi) in 458.7157ms [19:22:29 INF] Executed endpoint 'Volo.Forms.Questions.QuestionController.UpdateAsync (Volo.Forms.HttpApi)' [19:22:29 DBG] Added 0 entity changes to the current audit log [19:22:29 DBG] Added 0 entity changes to the current audit log [19:22:29 INF] Request finished HTTP/2 PUT https://localhost:44345/api/questions/807e2c84-9744-1095-d926-3a03d0665c52 application/json 485 - 500 - application/json;+charset=utf-8 706.6463ms [19:22:29 INF] Request starting HTTP/2 GET https://localhost:44345/images/logo/logo-dark.png - - [19:22:29 INF] Sending file. Request path: '/images/logo/logo-dark.png'. Physical path: 'E:\dev\SELFSERVICE\src\SELFSERVICE.Web\wwwroot\images\logo\logo-dark.png' [19:22:29 INF] Request finished HTTP/2 GET https://localhost:44345/images/logo/logo-dark.png - - - 200 4236 image/png 3.0548ms [19:22:36 DBG] Executing HealthCheck collector HostedService.
-
0
I've tried with
v5.2.1
as you said but couldn't reproduce that exception. Can you please share the steps to reproduce? -
0
If you do this within a tenant, there is a known issue fixed in 5.3.0-RC1 : https://support.abp.io/QA/Questions/2882
BUT 5.3.0-RC1 bring another bug. Hoping it will be solved in the next release.
-
0
Hope so.
Its a critical piece
-
0
I've tried with
v5.2.1
as you said but couldn't reproduce that exception. Can you please share the steps to reproduce?Means 5.2.1 doesnt have the mentioned bug ?
-
0
We have validated the problem. We'll be working on the next patch version. I'll share with you a workaround as soon as possible.
-
0
This problem has been already solved in
v5.2.2
.Since It's an entity related problem and can't override or replace entity class. So I can't suggest to you a workaround now, you can update to
5.2.2
Also your credit is refunded
-
0
Hi again.
For earlier version such as yours, you can add following class into your Domain project and replace & override the QuestionManager with the fixed code block.
I personally don't recommend to set protected or private properties via using reflection but in that case, it can be patched like this.
using System; using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Forms; using Volo.Forms.Forms; using Volo.Forms.Questions; using Volo.Forms.Questions.ChoosableItems; namespace YourProjectName; [ExposeServices(typeof(QuestionManager))] [Dependency(ReplaceServices = true)] public class MyQuestionManager : QuestionManager { protected IQuestionRepository questionRepository; public MyQuestionManager( IQuestionRepository questionRepository, IFormRepository formRepository, IGuidGenerator guidGenerator) : base(questionRepository, formRepository, guidGenerator) { this.questionRepository = questionRepository; } public override async Task<QuestionBase> UpdateAsync(Guid id, string title, int index, bool isRequired, string description, QuestionTypes questionType, bool hasOtherOption, List<(Guid Id, string value, bool isCorrect)> choiceList) { var question = await questionRepository.GetAsync(id); var questionId = question.Id; var formId = question.FormId; var creationDate = question.CreationTime; // This will be removed when EfCore bug is resolved: https://github.com/dotnet/efcore/issues/22016 // Since item with choice collection can't return single object; we can't remove choices over item. await ClearItemChoicesAsync(question); question = await questionRepository.GetAsync(id); await questionRepository.HardDeleteAsync(question, autoSave: true); var createdQuestion = CreateItemBasedOnType(questionType, questionId); createdQuestion .SetFormId(formId) .SetTitle(title) .SetIndex(index) .SetDescription(description); createdQuestion.SetRequired(isRequired); createdQuestion.SetOtherOption(hasOtherOption); if (createdQuestion is IChoosable choosableItem) { if (!(question is IChoosable)) { for (var i = 0; i < choiceList.Count; i++) { choosableItem.AddChoice(id: GuidGenerator.Create(), index: i + 1, value: choiceList[i].value, isCorrect: choiceList[i].isCorrect); } } else { UpdateIndexesOfChoiceList(choiceList); choosableItem.AddChoices(choiceList); } } createdQuestion.CreationTime = creationDate; createdQuestion.LastModificationTime = DateTime.Now; FixChoicesTenants(createdQuestion); await UpdateFormLastModificationDateAsync(createdQuestion.FormId); return await questionRepository.InsertAsync(createdQuestion, true); } private void FixChoicesTenants(QuestionBase createdQuestion) { if(createdQuestion is Checkbox checkbox) { foreach(var choice in checkbox.Choices) { SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id); } } if (createdQuestion is ChoiceMultiple choiceMultiple) { foreach(var choice in choiceMultiple.Choices) { SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id); } } if (createdQuestion is DropdownList dropdownList) { foreach(var choice in dropdownList.Choices) { SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id); } } } private void SetProperty<T>(T obj, string propertyName, object value) { typeof(T).GetProperty(propertyName)?.SetValue(obj, value); } }
-
0
This problem has been already solved in
v5.2.2
.Since It's an entity related problem and can't override or replace entity class. So I can't suggest to you a workaround now, you can update to
5.2.2
Also your credit is refunded
Have update my project to 5.2.2. At least i can create questions with options/ choice responses. But when submitting the filled form i get below error. Seems the tenant id is not filled in the DB yet the form requires log in hence hence user is already in a tenant when filling the form.
-
0
I couldn't reproduce the error.
Did you try creating a new form after updating to 5.2.2 and add questions / answers to newly created form?
-
0
This is the same issue as reported here (applies to 5.2.2 and 5.3.0-RC1): https://support.abp.io/QA/Questions/3067/530-RC1-Form-Multi-tenant-issue
-
0
I couldn't reproduce the error.
Did you try creating a new form after updating to 5.2.2 and add questions / answers to newly created form?
I created a new form ans added questions. The problem persists.
-
0
This is the same issue as reported here (applies to 5.2.2 and 5.3.0-RC1): https://support.abp.io/QA/Questions/3067/530-RC1-Form-Multi-tenant-issue
Yes, they seem same issue.
Thank you, we'll investigate more based on the steps in https://support.abp.io/QA/Questions/3067/530-RC1-Form-Multi-tenant-issue