ASP.NET Web API - AutoMapper不忽略可为空的布尔值

ttygqcqt  于 2022-12-24  发布在  .NET
关注(0)|答案(1)|浏览(124)

我正在用ASP API编写Web应用程序,并正在研究修改餐馆信息的方法。核心实体是餐馆,看起来像这样:

public class Restaurant
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string? Description { get; set; }
    public string Category { get; set; }
    public bool HasDelivery { get; set; }
    public string ContactEmail { get; set; }
    public string ContactNumber { get; set; }

    public int? CreatedById { get; set; }
    public virtual User CreatedBy { get; set; }

    public int AddressId { get; set; }
    public virtual Address Address { get; set; }

    public virtual List<Dish> Dishes { get; set; }
}

这里最重要的是什么-HasDelivery属性不能为空。它必须取true或false值中的一个。接下来,我有ModifyRestaurantDto类,当应用程序工作时,它作为来自主体的请求。就像下面这样:

public class ModifyRestaurantDto
{
    [MaxLength(25)]
    public string? Name { get; set; }

    [MaxLength(100)]
    public string? Description { get; set; }
    public bool? HasDelivery { get; set; }
}

为了简单起见,我只给出了几个允许更改的属性。注意,它们都是可以为空的类型。我还有一个名为UpdateAsync的服务方法,如下所示:

public async Task UpdateAsync(int id, ModifyRestaurantDto modifyRestaurantDto)
{
    var restaurant = await _dbContext
        .Restaurants
        .FirstOrDefaultAsync(r => r.Id == id)
        ?? throw new NotFoundException("Restaurant not found...");

    var authorizationResult = _authorizationService
        .AuthorizeAsync(
            _userContextService.User,
            restaurant,
            new ResourceOperationRequirement(ResourceOperation.Update))
        .Result;

    if (!authorizationResult.Succeeded) 
        throw new ForbidException();

    _mapper.Map(modifyRestaurantDto, restaurant);
    await _dbContext.SaveChangesAsync();
}

我想要实现的是只更改请求主体(在ModifyRestaurantDto中)中给定的值。例如,如果我的json主体看起来像这样

{
    "name": "Foo"
}

我不希望Description和HasDelivery属性发生变化。现在,我已经创建了AutoMapper配置文件,并在Program.cs中配置了它。

public class RestaurantMappingProfile : Profile
{
    public RestaurantMappingProfile()
    {
        CreateMap<ModifyRestaurantDto, Restaurant>()
            .ForAllMembers(opts => opts.Condition((src, dest, value) => value is not null));
    }
}

虽然给定的类型是string,但一切都能正常工作。问题是,无论如何,可为空的bool总是转换为false。我使用的是.NET 6.0,并在. csproj中启用了可为空和隐式Using。
您知道为什么AutoMapper只忽略可空布尔值吗?

hgqdbh6s

hgqdbh6s1#

我觉得这是一个bug。一个快速的修复方法是添加从bool?bool的Map:

CreateMap<bool?, bool>().ConvertUsing((src, dest) => src ?? dest);
CreateMap<ModifyRestaurantDto, Restaurant>()
    .ForAllMembers(opts => opts.Condition((_, _, v) => v is not null));

相关问题