Open Closed

UpdateAsync contains input data, not output (that has been modified by ValueConverter) #238


User avatar
0
alexander.nikonov created

I wonder why UpdateAsync returns INPUT data, even if the input data has been changed? For instance, I have the space truncating rule for my entity:

b.Property(x => x.Domain)
    .HasConversion(new ValueConverter<string, string>(v => v.Trim(), v => v.Trim()))
    .HasColumnName("C_DOMAIN").HasMaxLength(DbConsts.DomainMaxLength);
                

Despite this fact, the method returns INPUT data which does not have truncation:

public async Task<ModuleDto> UpdateAsync(ModuleKeyDto id, UpdateModuleDto input)
{
    var module = await _moduleRepository.GetAsync(m => m.ApplicationId == id.ApplicationId && m.ModuleId == id.ModuleId);
    if (module == null)
    {
        throw new UserFriendlyException("Module not found", ErrorCodes.NotFound);
    }
    ObjectMapper.Map(input, module);
    var updatedModule = await _moduleRepository.UpdateAsync(module); // updatedModule container non-truncated value that was present in module!!!
    await CurrentUnitOfWork.SaveChangesAsync();
    return ObjectMapper.Map<Module, ModuleDto>(updatedModule);
}

Looks like a bug? I can re-read the entity and it then will look allright, but don't want to make an extra trip to DB.


4 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi, see https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions

    Value converters allow property values to be converted when reading from or writing to the database.

    Value converters do not change property values when inserting and updating, but change parameter values. You should normalize DTO.

  • User Avatar
    0
    alexander.nikonov created

    OK, thanks, now I know the property values not changed, but parameter values instead. But what do you mean by DTO normalization? Carry on some operations on DTOs? But if so - it's easier just to re-read the entity to get correct up-to-date values.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Example :

    public class UpdateModuleDto
    {
        public string Name { get ;set ;}
    
        public void Normalize()
        {
            Name = Name.Trim();
        }
    }
    
    public async Task<ModuleDto> UpdateAsync(ModuleKeyDto id, UpdateModuleDto input)
    {
             input.Normalize();
             //......
    }
    
  • User Avatar
    0
    alexander.nikonov created

    Saying honestly, not a very good solution, imho. Usually DTO is just a bunch of fields and should not contain some functionality. Handling all the logic in OnModelCreating looks fine and logical. So - since it's not possible to get new data straight from update object - I think I will have to re-read the entity.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11