Base solution for your next web application

Activities of "daws"

Question

Hello,

Is it possible to have my users at the host level so that they're shared across tenants ?

So when I edit a user (or its permissions, or anything else), changes would be echoed to other tenants.

We're on Aspnetzero V8.8.0 angular + .net core

Answer

Hello, thanks for your answer.

My use case is as follows :

Usually, each of our customers manages a single site (= tenant).

However, we have one of our customers who manages two sites (two different tenants). This customer has several users and most of them should be able to connect to both tenants with the same username, role and permissions

.net core, angular, aspnetzero 8.8

In a manager, we read and update a serialized json from/to an abpsetting. We do this several times in a for loop over entity objects. At some point in the loop, the retrieved setting will be truncated (to a variable length), thus crashing the json parser. At the same time, in the database, the setting has been correctly set to a valid json value.

Here's our code :

The loop :

foreach (var entity in entities) 
    _myManager.UpdateEntityAsync(entity).GetAwaiter().GetResult();``

The manager :

    [UnitOfWork]
    public async Task UpdateEntityAsync(MyEntity entity)
    {
        await _myEntityRepository.UpdateAsync(entity);
        AddDateRangeToReprocess(entity.Id, new DateRange(entity.Start, entity.End));
    }
    [UnitOfWork]
    public void AddDateRangeToReprocess(short id, DateRange range)
    {
        var existingDateRanges = GetDateRangesToReprocess();

        if (existingDateRanges == null)
        {
            existingDateRanges = new Dictionary<short, List<DateRange>>();
        }

        if (!existingDateRanges.ContainsKey(id) || existingDateRanges[id] == null)
        {
            existingDateRanges.AddOrUpdateIfExist(id, new List<DateRange>());
        }

        if (!existingDateRanges[id].Any(x => x == range))
        {
            existingDateRanges[id].Add(range);
        }

        if (_tenantManager.AbpSession.TenantId.HasValue)
        {
            _settingManager.ChangeSettingForTenant(_tenantManager.AbpSession.TenantId.Value, "EntityRanges", JsonConvert.SerializeObject(existingDateRanges));
        }
    }
    [UnitOfWork]
    public Dictionary<short, List<DateRange>> GetDateRangesToReprocess()
    {
        return JsonConvert.DeserializeObject<Dictionary<short, List<DateRange>>>(_settingManager.GetSettingValue("EntityRanges"));
    }

Output example :

//Value of the setting in the database :
{"14":[{"Start":"2021-03-01T05:39:00Z","End":"2021-03-01T05:39:44Z","Duration":"00:00:44"},{"Start":"2021-03-08T16:51:45Z","End":"2021-03-08T16:52:05Z","Duration":"00:00:20"}]}

//Value of the setting when debugging in the manager (GetDateRangesToReprocess) :
{"14":[{"Start":"2021-03-01T05:39:00Z","End":"2021-03-01T05:39:44Z","Duration":"00:00:44"},{"Start":"2021-03-08T16:51:45Z","End":"2021-03-08T16:52:05Z",

There does not seem to be a specific length to which our setting is truncated.

We figured that maybe it had to do with the cache that was not invalidated properly ?

Hi @ismcagdas

We ended up creating a separate table and not using an abpsetting for this. It's faster, it's useful for other use cases and it works fine. Thank you anyway for your reply !

Angular .net core. We are currently migrating from aspnetzero 8.8 to 10.3.

In the RoleAppService there's this method :

public async Task <ListResultDto> GetRoles(GetRolesInput input)

When we query the swagger endpoint, we get this :

"/api/services/app/Role/GetRoles": {
      "get": {
        "tags": [
          "Role"
        ],
        "operationId": "ApiServicesAppRoleGetrolesGet",
        "parameters": [
          {
            "name": "Permissions",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ListResultDtoOfRoleListDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResultDtoOfRoleListDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResultDtoOfRoleListDto"
                }
              }
            }
          }
        }
      }
    },

Why does swagger reduce GetRolesInput to Permissions (which is its only Property) ? In the frontend, it triggers compilation errors in the roles.component which doesn't know what a GetRolesInput object is anymore.

I checked in your code and there it's generated just fine. I tried adding other properties to the class, they all seem to be split by swagger. I copied the service.config.nswag from aspnetzero and I also double checked the Startup file in the Web.Host project.

Did I miss a swagger config option somewhere ?

Thanks

I don't think it has anything to do with the service-proxies generation.

As you can see in my request, the swagger endpoint generated in the backend (https://localhost:44301/swagger/v1/swagger.json) already splits the Input class into its properties.

There must be some swagger configuration parameter enabling the split in the backend but I can't seem to find it...

Our mistake. When migrating, we omitted the change which adds the [HttpPost] decorator on the GetRoles method in the RoleAppService.

Without it, it seems that the method is recognized as a GET method and therefore has its input parameters split.

Thanks for the support.

  • What is your product version? 10.3
  • What is your product type (Angular or MVC)? Angular
  • What is product framework type (.net framework or .net core)? ?Net Core
  • What is ABP Framework version? 6.3.1

Dear support, I am injecting objects through an IRepository, and the CreatorUserId is filled with my current UserId = 2 (auto detected by ABPSession) when inserted into DB.

I want to modify the UserId of the object, to set it to null. Following your documentation, I use the session.Use (allowing a "long?" parameter) method but when I set the 2nd parameter as null, the UserId is still equals to "2".

If I use a non null value (e.g. "10"), this new value will correctly inserted into db.

Is there any info related to the null, that I am not aware of ?

public void InsertOrUpdateAreas(IList areas)
{
using (_session.Use(_session.TenantId, null))

        {
            var tenantId = _session.TenantId; //2
            var userId = _session.UserId; //2 ==> abp gives "2" instead of null

            foreach (var area in areas)
                    _areaRepository.Insert(area);

            CurrentUnitOfWork.SaveChanges();
        }
    }

Thanks for the hint but I am still stuck.

If I override GetAuditUserId, of course I can force it to return null but I want to get a null value only in a specific call, not for all methods. In all other method (except the one listed in my other post), it is important to keep the UserId filled in.

thus, I wanted to use this function https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp/Runtime/Session/AbpSessionBase.cs#L40 which is supposed to take nullable userId but which does not work.

I halso have another possibility which is to give a boolean parameter to the dbcontext TestDbContext : AbpZeroDbContext once the program is started and, depending of this boolean parameter, returning null in GetAuditUserId(). But I can not find a way to give a parameter to the dbcontext when it is created.

do you have any more tips ?

thanks

        protected override long? GetAuditUserId()
        {
            if (AbpSession.UserId.HasValue &&
                CurrentUnitOfWorkProvider != null &&
                CurrentUnitOfWorkProvider.Current != null &&
                CurrentUnitOfWorkProvider.Current.GetTenantId() == AbpSession.TenantId)
            {
                return AbpSession.UserId;
            }

            return null;
        }

modifing the httpcontext or overriding the abpsession was too much complex for my use case.

I have found the solution, simply use

using (_unitOfWorkManager.Current.DisableAuditing(new string[]{ AbpAuditFields.CreationUserId}))

Showing 111 to 120 of 126 entries