我正在尝试使用自动映射器映射两个类。问题源于我的类具有已编码和未编码的状态,该状态将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;}
}
映射器
CreateMap<CompanyDTO, CompanyVO>()
.BeforeMap((src, dst) => Utils.DecodeState(src)) // DecodeState() toggles IsEncoded to false
.ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Id); // will automatically convert string src.Id to int
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
...
}
问题是自动映射器使用了错误的构造函数,您必须通过在映射配置中使用.ConstructUsing()
指定要使用的构造函数。
这是自动映射器执行的事件的当前顺序:
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);
我的用例允许我不带任何参数地使用构造器,尽管我也可以很容易地做到这一点:
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);