Hi, I want to be sure about something.
We want to host our Web Api on 2 servers. Apart from the Framework, we do not have any server-based processes such as session, local server cache, which we specially develop. We use a single database.
Should api requests made by clients go to the web api server where the client is logged in? Does hosting the Web Api on multiple servers create problems in Authorization or other situations?
Thanks
Here is github issue.
Sorry it was our mistake. I saw that in DbContextModelSnapshot, ObjectiveId of DevelopmentObjectiveCategoryMapping is described as Unique like b.HasIndex("ObjectiveId").IsUnique().
DevelopmentObjectiveCategoryMapping ia a many-to-many table. When we insert 3 entities into it we only see that only the latest one is inserted. Do you have any idea why this could be happening?
public async Task CreateObjective(CreateDevelopmentObjectiveInput input)
{
var o1 = new DevelopmentObjective
{
FormId = input.FormId,
TemplateId = input.TemplateId,
MeasureOfSuccess = input.MeasureOfSuccess,
CompletionDate = input.CompletionDate,
Status = input.Status
};
await _objectiveRepository.InsertAndGetIdAsync(o1);
var docm1 = new DevelopmentObjectiveCategoryMapping
{
ObjectiveId = o1.Id,
CategoryId = input.ObjectiveCategory.CategoryId,
OtherCategoryName = input.ObjectiveCategory.OtherCategoryName,
CategoryDescription = input.ObjectiveCategory.CategoryDescription
};
var docm2 = new DevelopmentObjectiveCategoryMapping
{
ObjectiveId = o1.Id,
CategoryId = input.ObjectiveCategory.CategoryId,
OtherCategoryName = input.ObjectiveCategory.OtherCategoryName,
CategoryDescription = input.ObjectiveCategory.CategoryDescription
};
var docm3 = new DevelopmentObjectiveCategoryMapping
{
ObjectiveId = o1.Id,
CategoryId = input.ObjectiveCategory.CategoryId,
OtherCategoryName = input.ObjectiveCategory.OtherCategoryName,
CategoryDescription = input.ObjectiveCategory.CategoryDescription
};
await _objectiveCategoryMappingRepository.InsertAndGetIdAsync(docm1);
await _objectiveCategoryMappingRepository.InsertAndGetIdAsync(docm2);
await _objectiveCategoryMappingRepository.InsertAndGetIdAsync(docm3);
}
Thank you for your fast reply!
We want to create a new user with the help of a backround task by using Hangfire integraion of ABP for 16.000 Employees which is coming from our SAP service. Below is the code which demonstrates for a single creating action. We even couldn't create a single user. There is our code and exception. Please help us.
public class SyncCreationUserJob : BackgroundJob<SyncCreationUserArgs>, ITransientDependency
{
private readonly IUserAppService _userAppService;
private readonly UserManager _userManager;
public SyncCreationUserJob(
IUserAppService userAppService,
UserManager userManager
)
{
_userAppService = userAppService;
_userManager = userManager;
}
public override void Execute(SyncCreationUserArgs args)
{
using (_userManager.AbpSession.Use(null, 1))
{
var createUserTask = _userAppService.CreateOrUpdateUser(new CreateOrUpdateUserInput
{
User = new UserEditDto
{
UserName = "TestUser",
EmailAddress = "[email protected]",
Name = "John",
Surname = "Nash",
PhoneNumber = "5441111111",
IsActive = true,
IsLockoutEnabled = false,
IsTwoFactorEnabled = false,
ShouldChangePasswordOnNextLogin = false,
Password = Guid.NewGuid().ToString().Substring(0, 30)
},
AssignedRoleNames = new string[] { }
});
createUserTask.ContinueWith(t =>
{
var ex = t.Exception;
}, TaskContinuationOptions.OnlyOnFaulted);
}
}
Message: One or more errors occurred. (Cannot access a disposed object. Object name: 'UserManagerProxy'.)
Stack Trace:
at Microsoft.AspNetCore.Identity.UserManager1.ThrowIfDisposed() at Microsoft.AspNetCore.Identity.UserManager
1.CreateAsync(TUser user)
at Abp.Authorization.Users.AbpUserManager2.CreateAsync(TUser user) in D:\Github\aspnetboilerplate\src\Abp.ZeroCore\Authorization\Users\AbpUserManager.cs:line 130 at Apollo.Authorization.Users.UserAppService.CreateUserAsync(CreateOrUpdateUserInput input) in C:\Yazilim\Apollo\dev\aspnet-core\src\Apollo.Application\Authorization\Users\UserAppService.cs:line 338 at Abp.Threading.InternalAsyncHelper.AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func
1 postAction, Action1 finalAction) in D:\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:line 35 at Apollo.Authorization.Users.UserAppService.CreateOrUpdateUser(CreateOrUpdateUserInput input) in C:\Yazilim\Apollo\dev\aspnet-core\src\Apollo.Application\Authorization\Users\UserAppService.cs:line 237 at Abp.Threading.InternalAsyncHelper.AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func
1 postAction, Action1 finalAction) in D:\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:line 35 at Abp.Threading.InternalAsyncHelper.AwaitTaskWithFinally(Task actualReturnValue, Action
1 finalAction) in D:\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs:line 15
Dear friend, thanks for your reply. Below is my insert method and it works with navigation props.
[AbpAuthorize (AppPermissions.Pages_PerformanceManagement_Objectives_Create)]
private async Task Create (CreateOrEditObjectiveDto input) {
var objective = ObjectMapper.Map<Objective> (input);
if (AbpSession.TenantId != null)
objective.TenantId = AbpSession.TenantId;
await _objectiveRepository.InsertAsync (objective);
}
Problem is with update method for navigation props. I thought i did something wrong and that's why i'm having this problem. I refactored my code as you recommended, below it is. But i'm totally not sure if it's good practice. There should be a native support for this. If i can find, i will share it with you.
[AbpAuthorize(AppPermissions.Pages_PerformanceManagement_Objectives_Edit)]
private async Task Update(CreateOrEditObjectiveDto input)
{
var objective = await _objectiveRepository.FirstOrDefaultAsync((long)input.Id);
ObjectMapper.Map(input, objective);
await _objectiveRepository.UpdateAsync(objective);
await UpdateToleranceLimits(input);
}
[AbpAuthorize(AppPermissions.Pages_PerformanceManagement_Objectives_Edit)]
private async Task UpdateToleranceLimits(CreateOrEditObjectiveDto input)
{
foreach (var toleranceLimitDto in input.ToleranceLimits)
await _objectiveToleranceLimitRepository.UpdateAsync(
ObjectMapper.Map<ObjectiveToleranceLimit>(toleranceLimitDto));
}
If you want to update in the Update method, You first need to query the relevant ObjectiveToleranceLimit.
Could you please show me how to do it?
I'm trying to simply update navigation properties of an entity but i couldn't succeed. I did a some seaching on the internet but those solution didn't work for me. i actually solved this easy-looking problem but the way i solved it did not satisfy me.
Here is an appropriate forum post and answer by @ismcagdas. Here is an appropriate sof question.
Error message.
ERROR 2019-01-08 08:52:34,428 [86 ] Mvc.ExceptionHandling.AbpExceptionFilter - An error occurred while updating the entries. See the inner exception for details. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'ObjectiveToleranceLimits' when IDENTITY_INSERT is set to OFF. at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__122_0(Task`1 result)
Our simlified entities and dtos.
[Table ("Objectives", Schema = "Apl")]
[Audited]
public class Objective : FullAuditedEntity<long>, IMayHaveTenant {
public int? TenantId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<ObjectiveToleranceLimit> ToleranceLimits { get; set; }
}
[Table ("ObjectiveToleranceLimits", Schema = "Apl")]
[Audited]
public class ObjectiveToleranceLimit : Entity<long>, IMayHaveTenant {
public int? TenantId { get; set; }
public int? ToleranceLimit { get; set; }
[CanBeNull]
[ForeignKey (nameof (ObjectiveId))]
public long? ObjectiveId { get; set; }
public Objective Objective { get; set; }
}
public class CreateOrEditObjectiveDto : EntityDto<long?> {
[Required]
public string Name { get; set; }
public IList<CreateOrEditObjectiveToleranceLimitDto> ToleranceLimits { get; set; }
}
public class CreateOrEditObjectiveToleranceLimitDto : EntityDto<long?> {
public int? ToleranceLimit { get; set; }
public long? ObjectiveId { get; set; }
}
[AbpAuthorize (AppPermissions.Pages_PerformanceManagement_Objectives_Edit)]
private async Task Update (CreateOrEditObjectiveDto input) {
var objective = await _objectiveRepository.FirstOrDefaultAsync ((long) input.Id);
ObjectMapper.Map (input, objective);
await _objectiveRepository.UpdateAsync (objective);
// How to make it work?
// Step#1
// igone ToleranceLimits mapping in CustomDtoMapper.cs
// configuration.CreateMap<CreateOrEditObjectiveDto, Objective> ()
// .ForMember (dto => dto.ToleranceLimits, options => options.Ignore ());
// Step#2
// do a manual update
// foreach (var toleranceLimitDto in input.ToleranceLimits) {
// await _objectiveToleranceLimitRepository.UpdateAsync (
// ObjectMapper.Map<ObjectiveToleranceLimit> (toleranceLimitDto));
// }
}