代码之家  ›  专栏  ›  技术社区  ›  skolima

如何使用AutoMapper将字节[]转换为字符串?

  •  2
  • skolima  · 技术社区  · 3 年前

    尝试将具有byte[]类型属性的对象转换为具有string类型匹配属性的对象时,AutoMapper中出现以下错误:

    System.InvalidOperationException:缺少从System.Byte到System.Char的映射。使用CreateMap创建<字节,字符>。

    我尝试使用自定义类型转换器,但它们似乎不起作用(有或没有它们都会出现相同的错误)。我能够映射特定属性,但我正在尝试创建一些可以应用于整个项目的东西(我的大多数实体都包含一个用于乐观锁定的RowVersion)。

    我的代码看起来像这样。。。

    public class AutoMapperProfile : AutoMapper.Profile
    {
        public AutoMapperProfile()
        {
            CreateMap<byte[], string>().ConvertUsing<ByteArrayToStringTypeConverter>();
            CreateMap<string, byte[]>().ConvertUsing<StringToByteArrayTypeConverter>();
            CreateMap<MyFirstClass, MySecondClass>();
        }
    }
    public class MyFirstClass
    {
        public string Name { get; set; }
        public byte[] RowVersion { get; set; }
    }
    
    public class MySecondClass
    {
        public string Name { get; set; }
        public string RowVersion { get; set; }
    }
    
    public class ByteArrayToStringTypeConverter : ITypeConverter<byte[], string>
    {
        public string Convert(byte[] source, string destination, ResolutionContext context)
        {
            return System.Convert.ToBase64String(source);
        }
    }
    
    public class StringToByteArrayTypeConverter : ITypeConverter<string, byte[]>
    {
        public byte[] Convert(string source, byte[] destination, ResolutionContext context)
        {
            return System.Convert.FromBase64String(source);
        }
    }
    

    这是一个.NET5,ASP.NETCore,WebAPI项目。

    1 回复  |  直到 3 年前
        1
  •  3
  •   abdusco    3 年前

    TypeConverter 我这边的工作很好:

    class DatabaseRecord
    {
        public byte[] RowVersion { get; set; }
    }
    
    class Dto
    {
        public string RowVersion { get; set; }
    }
    

    这个映射配置

    public class Mappings : Profile
    {
        public static IMapper Mapper = new MapperConfiguration(c => c.AddProfile(new Mappings())).CreateMapper();
    
        public Mappings()
        {
            CreateMap<string, byte[]>().ConvertUsing<Base64Converter>();
            CreateMap<byte[], string>().ConvertUsing<Base64Converter>();
            CreateMap<DatabaseRecord, Dto>().ReverseMap();
        }
    
        private class Base64Converter : ITypeConverter<string, byte[]>, ITypeConverter<byte[], string>
        {
            public byte[] Convert(string source, byte[] destination, ResolutionContext context) 
                => System.Convert.FromBase64String(source);
    
            public string Convert(byte[] source, string destination, ResolutionContext context) 
                => System.Convert.ToBase64String(source);
        }
    }
    

    @Lucian Bargaoanu 指出这可以通过内联转换器缩短:

    CreateMap<string, byte[]>().ConvertUsing(s => System.Convert.FromBase64String(s));
    CreateMap<byte[], string>().ConvertUsing(bytes => System.Convert.ToBase64String(bytes));
    CreateMap<DatabaseRecord, Dto>().ReverseMap();
    

    我可以皈依 string (64)至 byte[]

    var result = Mappings.Mapper.Map<Dto>(new DatabaseRecord
    {
        RowVersion = new byte[]{104,101,108,108,111} // "hello"
    });
    Console.WriteLine(result.RowVersion); // outputs "aGVsbG8="
    
    var record = Mappings.Mapper.Map<DatabaseRecord>(new Dto
    {
        RowVersion = "aGVsbG8=" // "hello" in base64
    });
    // record.RowVersion == 104,101,108,108,111