Base solution for your next web application
Open Closed

TenantManager CreateAsync(tenant) clears Current UnitOfWork #9959


User avatar
0
tbentley created

I am running the ASP.NET Core & Angular version v9.0.1

I am able to add a tenant using the Swagger call and also from the angular client. However, when I call the same API using the Public website I get an error. I tracked it down to the TenantManager

await CreateAsync(tenant);
await _unitOfWorkManager.Current.SaveChangesAsync();

The CreateAsync(tenant) creates the tenant record but it sets _unitOfWorkManager.Current to null.

Does anyone know why this is happening and how to correct it?

Thanks... Terry


7 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @tbentley

    Could you share;

    1. How do you call tenant creation API from public website
    2. And, which API you are calling for tenant creation ?

    Thanks,

  • User Avatar
    0
    tbentley created
    1. I created a MerchantController
            [HttpPost]
            public IActionResult Index(MerchantIndexViewModel input)
            {
              ...
              //validation
              ...
              //Initialize tenant object
              ...
              //Call to the API
              _tenantAppService.CreateRestaurantTenant(tenant);
    
    1. I am using a slight variation of the original CreateTenant APi adding the additional properties I needed. I kept the [UnitOfWork(IsDisabled=true] attribute on it but I also added an [AllowAnonymous] attrribute. could that be what causes the Current UnitOfWork to be nullified in CreateAsync(tenant)?
  • User Avatar
    0
    tbentley created

    Just tried calling the CreateRestaurantTenant(tenant) using the _tenantRegistrationAppService class and got the same error.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Yes, the reason is [UnitOfWork(IsDisabled=true] attribute. If you use this attribute, you need to start a unitOfWork manually when you need it.

    using (var uow = _unitOfWorkManager.Begin())
    {
        // Here Current UnitOfWork will not be null
    }
    
  • User Avatar
    0
    tbentley created

    Thanks but I tried that if I start a new unit of work it causes the line

    CheckErrors(await _roleManager.CreateStaticRoles(tenant.Id));
    

    to give me the following error:

    System.ObjectDisposedException: Cannot access a disposed object. Object name: 'RoleManagerProxy'.

    Why does the CreateAsync(tenant) end the UnitOfWork

    using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
                {
                    //Create tenant
                    var tenant = new Tenant(tenancyName, name)
                    {
                        IsActive = isActive,
                        EditionId = editionId,
                        SubscriptionEndDateUtc = subscriptionEndDate?.ToUniversalTime(),
                        IsInTrialPeriod = isInTrialPeriod,
                        ConnectionString = connectionString.IsNullOrWhiteSpace() ? null : SimpleStringCipher.Instance.Encrypt(connectionString),
                        Address = address,
                        City = city,
                        Region = region,
                        PostalCode = postalCode,
                        Phone = phone,
                        EmailAddress = emailAddress
                    };
    
                    await CreateAsync(tenant);
                    await _unitOfWorkManager.Current.SaveChangesAsync(); //To get new tenant's id.
    
                      //We are working entities of new tenant, so changing tenant filter
                    using (_unitOfWorkManager.Current.SetTenantId(tenant.Id))
                    {
                        //Create static roles for new tenant
                        CheckErrors(await _roleManager.CreateStaticRoles(tenant.Id));
                        await _unitOfWorkManager.Current.SaveChangesAsync(); //To get static role ids
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @tbentley

    Could you share your entire class ?

  • User Avatar
    0
    tbentley created

    Thank you for your help. I was able to resolve the issue.

    There were actually two things I needed to correct the problem. I didn't realize I needed the [UnitOfWork] attribute in the Controller (I had it disabled on the API) Also, I was not calling the API Asynchronously.