Невозможно сопоставить байт [] или байт []? (обнуляемый байт []) с помощью функции автоматического преобразования ForCtorParam

#c# #automapper #mapper #nullable-reference-types #automapper-6

#c# #automapper #mapper #nullable-reference-types #automapper-6

Вопрос:

Невозможно сопоставить байт [] или байт []? (обнуляемый байт []) используя функцию автоматической настройки ForCtorParam, я получаю сообщение об ошибке ниже

AutoMapper.Исключение AutoMapperConfigurationException: обнаружены несопоставленные элементы. Просмотрите типы и элементы ниже. Добавьте пользовательское выражение сопоставления, игнорируйте, добавьте пользовательский преобразователь или измените тип источника / назначения для конструктора без соответствия, добавьте аргумент без аргументов, добавьте необязательные аргументы или сопоставьте все параметры конструктора ================================================================================== Model -> ModelDto (список членов назначения) AutoMapperForCtorParamTest Model -> AutoMapperForCtorParamTest ModelDto (список членов назначения) Не сопоставленные свойства: код LinkId

Пример кода для воссоздания ниже

 public class AutoMapperForCtorParamTest
    {
        private readonly IMapper mapper;

        public AutoMapperForCtorParamTest()
        {
            mapper = new Mapper(new MapperConfiguration(
                cfg =>
                    {
                        cfg.AddProfile<ModelMapperProfile>();
                    }));
        }

        [Fact]
        public void MapAllProperties()
        {
            mapper.ConfigurationProvider.AssertConfigurationIsValid();
        }

        public class ModelMapperProfile : Profile
        {
            public ModelMapperProfile()
            {
                var defaultCode = Guid.NewGuid().ToByteArray();

                CreateMap<Model, ModelDto>()
                    .ForCtorParam("type", cfg => cfg.MapFrom(x => 1))
                    .ForCtorParam("code", cfg => cfg.MapFrom<byte[]>(x => defaultCode))
                    .ForCtorParam("linkId", cfg => cfg.MapFrom<byte[]?>(x => null));
            }
        }

        public class ModelDto
        {
            public ModelDto(int id, string name, int type, byte[] code, byte[]? linkId)
            {
                Id = id;
                Name = name;
                Type = type;
                Code = code;
                LinkId = linkId;
            }

            public int Id { get; }

            public string Name { get; }

            public int Type { get; }

            public byte[] Code { get; }

            public byte[]? LinkId { get; }
        }

        public class Model
        {
            public Model(int id, string name)
            {
                Id = id;
                Name = name;
            }

            public int Id { get; }

            public string Name { get; }
        }
    }

  

Примечание:

  1. Я использую ядро dotnet 3.1 с включенными обнуляемыми типами

  2. Я не хочу использовать построение с использованием или преобразование с использованием функций

  3. Я использую Automapper версии 10.0.0

Комментарии:

1. Я воспроизвел проблему здесь . Я добавил два отсутствующих параметра ctor и игнорирую оба пропущенных свойства, потому что они отображаются ctor. Это «решает» ошибку проверки конфигурации, но она ведет себя не так, как ожидалось, поскольку LinkId содержит пустой массив вместо null .

2. Проблема решается с помощью this.AllowNullCollections = true; in profile ctor.

3. Спасибо @Sebastian Schumann, это работает так, как ожидалось, но выглядит немного странно, поскольку элемент был сопоставлен и проигнорирован в той же конфигурации. Это рекомендуемый способ или обходной путь?

4. Сам элемент не сопоставлен. Существует сопоставление для параметра ctor. Но это обходной путь. Вот почему я не добавляю это в качестве ответа, потому что я не понимаю, почему то же самое работает для Type свойства. Это свойство не нужно игнорировать, оно выглядит так же, как Code или LinkId . Отличаются только типы. Но если для каждого свойства требуется сопоставление, также должно быть игнорирование (или сопоставление) для Type . Я не совсем понимаю это поведение и надеюсь, что найдется кто-нибудь, кто ответит на этот вопрос и опишет этот проводной факт.

5. Да, я согласен, проблема в byte[] , ForCtorParam map работает для других типов. В любом случае спасибо за вашу помощь.

Ответ №1:

Использовать:

 .ForCtorParam("text", opt => opt.MapFrom<byte[]?>(src => null));
  

В моем случае (строка) Я исправил это с помощью:

 .ForCtorParam("text", opt => opt.MapFrom<string>(src => null));