使用接口类型定义的属性从动态映射到类型

时间:2019-01-10 15:53:04

标签: c# .net dynamic automapper

围绕此的上下文是我想将public class LabelsDeserializer implements JsonDeserializer<Labels> { @Override public Labels deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { if (!jsonElement.isJsonNull()) { Labels label = new Labels(); jsonElement.getAsJsonObject().entrySet().forEach(entry -> label.getFields().put(entry.getKey(), entry.getValue().getAsString())); return label; } else { return null; } } } 精简结果映射到对象,并且该对象具有接口类型的属性:

dynamic

动态对象转换是直接的,但是我无法配置AutoMapper来告诉它如何处理接口。

public class TargetModel
{
    public int Id { get; set; }
    public IAddress AbstractAddress { get; set; }
}

我试图告诉它如何处理财产:

dynamic sourceModel = new ExpandoObject();

// flat model - id should map to TargetModel, Address01 will map to a nested type Address on TargetModel
sourceModel.Id = 1;
sourceModel.Address01 = "address01";

// for debugging purposes address maps ok from dynamic
Address address = Mapper.Map<Address>(sourceModel);

// this maps, but AbstractAddress is null - I need to config AutoMapper to understand how to map IAddress to Address
TargetModel target = Mapper.Map<TargetModel>(sourceModel);

哪个失败:

  

System.ArgumentException:无法创建接口类型的实例

所以我试图暗示具体的内容:

CreateMap<ExpandoObject, TargetModel>()
    .ForMember(y => y.AbstractAddress, opts => opts.MapFrom(f => f));

无法解决问题,并且仍然存在异常。

我查看了以下问题/概念,并尝试了各种配置选项,但仍无法使地图正常工作

1 个答案:

答案 0 :(得分:1)

这试图将module.exports.getCheckEmail = function(req, res){ var emailSender = '11wicketsfantasy@gmail.com'; var data = req.query; var emailToCheck = data.email; var i = 0; var type = 'success'; var message = 'Email is valid' // Finding domain of email address let domain = emailToCheck.split('@')[1]; dns.resolveMx(domain, function(err, addresses) { if(typeof addresses == 'undefined' || addresses == null) { res.status(200).json({ type: "error", message: 'No MX Records Found' }); } else { // If MX Records are found var tempMx = JSON.stringify(addresses); var mxRecords = JSON.parse(tempMx); // Getting minimum mx priority value var min = Math.min.apply( null, mxRecords.map((v) => v.priority)); var mxDomainArray = mxRecords.filter((it) => { return it.priority === min; }); var mxDomain = mxDomainArray[0].exchange; console.log('1 mx: '+mxDomain); const TELNET_PORT = 25; const conn = net.createConnection(TELNET_PORT, mxDomain); conn.setEncoding('ascii'); conn.setTimeout(6000); conn.on('error', function() { res.status(200).json({ type: "error", message: 'Error! There was some error during connection to mail server' }); conn.destroy(); }); conn.on('false', function () { res.status(200).json({ type: "error", message: 'False! There was some error during connection to mail server' }); conn.removeAllListeners(); conn.destroy(); }); console.log('before connect'); conn.on('connect', () => { console.log('inside connect'); conn.on('prompt', function () { const EOL = '\r\n'; conn.write(`helo ${mxDomain}` + EOL); conn.write(`mail from: <${emailSender}>` + EOL); conn.write(`rcpt to: <${emailToCheck}>` + EOL); conn.write('quit' + EOL); }); console.log('after conn'); conn.on('undetermined', function () { res.status(200).json({ type: "error", message: 'Undetermined! Mail server was undetermined' }); conn.removeAllListeners(); conn.destroy(); //destroy socket manually }); conn.on('timeout', () => { console.log('inside timeout'); // type = "timeout"; // messsage = "Your email server is not responding. Kindly use different email id"; res.status(200).json({ type: "timeout", message: 'Your email server is not responding. Kindly use different email id.' }); //console.log('timeout from conn.on'); conn.removeAllListeners(); conn.destroy(); }); conn.on('data', data => { console.log(data); const response = data.toString().trim(); // console.log("Data: "+response); if (response.startsWith('220') || response.startsWith('250') || response.startsWith('221') ) { conn.emit('prompt'); } else { type = 'error'; message = data; } }); conn.on('end', () => { res.status(200).json({ type: type, message: message }); conn.removeAllListeners(); conn.destroy(); }); }); } }); } //end module 中的string映射到目标类型中的ExpandoObject。显然,它无法创建IAddress的实例来填充,因此您必须在映射中自己实现。

如果您的模型如下所示:

IAddress

然后您的配置和设置如下所示:

public class TargetModel
{
    public int Id { get; set; }
    public IAddress AbstractAddress { get; set; }
}

public interface IAddress
{
    string Address01 { get; set; }
}

public class Address : IAddress
{
    public string Address01 { get; set; }
}

我只是将其用作public void MappingTests() { dynamic sourceModel = new ExpandoObject(); // flat model - id should map to TargetModel, Address01 will map to a nested type Address on TargetModel sourceModel.Id = 1; sourceModel.Address01 = "address01"; Mapper.Initialize(cfg => { cfg.CreateMap<ExpandoObject, TargetModel>() .ForMember(dest => dest.AbstractAddress, opt => opt.MapFrom(src => new Address() { Address01 = src.First(kvp => kvp.Key == "Address01").Value.ToString() })) .ForMember(destinationMember => destinationMember.Id, opt => opt.MapFrom(src => src.First(kvp => kvp.Key == "Id").Value)); }); TargetModel target = Mapper.Map<TargetModel>(sourceModel); } ,但您也可以通过强制转换将expando对象像字典一样对待。

IEnumerable<KeyValuePair<string, object>>