Automapper бросает "Входная строка не в правильном формате" - PullRequest
0 голосов
/ 07 февраля 2020

Я пытаюсь отобразить два класса, используя autopper. Проблема связана с тем, что мой класс имеет закодированное и незакодированное состояние, которое изменяет значение того, что находится в поле Id, с запутанной строки на строку, которая может быть проанализирована в int, но у меня сложилось впечатление, что я обрабатываю это должным образом, чтобы не было проблем с синтаксическим анализом.

Несмотря на то, что я декодирую свое состояние в .BeforeMap(), я все равно получаю сообщение о том, что ввод неправильного типа.

Классы

public class CompanyDTO {
  public CompanyDTO(){
    IsEncoded = true;
  }

  private int id { get; set; }
  public string Id
  {
      get
      {
          return GetIdValue(id);
      }
      set
      {
          id = SetIdValue(value);
      }
  }

  public bool IsEncoded {get; private set;}

  private string GetIdValue(string v){
    return isEncoded ? Utils.EncodeParam(v) : v.ToString(); // EncodeParam() performs encoding algorithm
  }

  private void SetIdValue(string v) {
    var intValue = v.TryParseInt(-1); // TryParseInt() custom extension to parse string to int else return parameter (-1)
    return intValue == -1 ? Utils.DecodeParam(v) : intValue; // DecodeParam() performs decoding algorithm
  }
}

public class CompanyVO {
  public CompanyVO() {}
  public CompanyVO(int id) {
    Id = id;
  }
  public int Id {get; set;}
}

Mappers

CreateMap<CompanyDTO, CompanyVO>()
  .BeforeMap((src, dst) => Utils.DecodeState(src)) // DecodeState() toggles IsEncoded to false
  .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id.TryParseInt(-1));

CreateMap<CompanyVO, CompanyDTO>()
  .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id.ToString());

Реализация

public void AddCompany(CompanyDTO company) {
  Mapper.Map<CompanyVO>(company); // Error: Input string was not in a correct format
  ...
}

1 Ответ

0 голосов
/ 07 февраля 2020

Проблема в том, что неправильный конструктор используется autopper, и вы должны указать, какой конструктор использовать, используя .ConstructUsing() в конфигурации карты.

Это текущий порядок событий, которые принимает Autopper. :

  1. Запуск конструктора для целевого типа (я не уверен, как autopper выбирает какой из них запускать)
public CompanyVO(int id) { // Error: passed id is the encoded string, not the decoded version and not an int
  Id = id;
}
Выполнить .BeforeMap() Выполнить преобразователи

Ошибка может быть устранена путем указания конструктора, который будет использоваться в автоматическом преобразователе.

CreateMap<CompanyDTO, CompanyVO>()
  .BeforeMap((src, dst) => Utils.DecodeState(src))
  .ConstructUsing(src => new CompanyVO()) // set constructor to the parameter-less one
  .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id.TryParseInt(-1));

Мое использование -case позволил мне использовать конструктор без каких-либо параметров, хотя я мог бы просто сделать это тоже:

CreateMap<CompanyDTO, CompanyVO>()
  .ConstructUsing(src => {
    Utils.DecodeState(src)
    return new CompanyVO(src.Id.TryParseInt(-1))
  })
  .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id.TryParseInt(-1));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...