如何使用Automapper进行映射

时间:2017-02-21 11:54:19

标签: c# asp.net json json.net automapper

我需要映射下面的情景。

public class Customer
{
    public string CustomerJson { get; set; }
}

public class CustomerTO
{
     public object CustomerJson { get; set; }
}

从DAL我得到CustomerJson值如下。

Customer.CustomerJson = {
    "name": "Ram",
    "city": "India"
}

我需要反序列化这个字符串。所以我在映射时尝试了以下内容。

var config = new MapperConfiguration(cfg =>
                    {
                        cfg.CreateMap<Customer, CustomerTO>()
                        .ForMember(dest => dest.CustName, opt => opt.MapFrom(src => JsonConvert.DeserializeObject(src.CustName)));
                    });

但是这给了我运行时错误。

  

未处理的异常:AutoMapper.AutoMapperMappingException:错误映射类型。

所以我保持简单。

var config = new MapperConfiguration(cfg =>
                    {
                        cfg.CreateMap<Customer, CustomerTO>()
                        .ForMember(dest => dest.CustName, opt => opt.MapFrom(src => (src.CustName));
                    });

我尝试在消费时对其进行反序列化。但是这会给编译时错误。

var custJson = JsonConvert.DeserializeObject(customerTO.CustomerJson );
  

错误2'Newtonsoft.Json.JsonConvert.DeserializeObject(string)'的最佳重载方法匹配有一些无效的参数

我知道customerTO.CustomerJson不是字符串,但我该如何进行必要的映射呢?

感谢。

2 个答案:

答案 0 :(得分:2)

根据您的previous question并根据上述信息,您似乎会混淆您在此处尝试做的事情。

因此,我将合并两者的数据以试图解决问题。

实体类:

public class Customer
{
    public int CustomerId {get; set; }
    public string CustomerName { get; set; }
    public string CustomerJson { get; set; }
}

public class CustomerTO
{
    public int CustId { get; set; }
    public object CustData { get; set; }
    public object CustomerJson { get; set; }
}

AppMapper类:

public static class AppMapper
{
    public static MapperConfiguration Mapping()
    {
        return new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Customer, CustomerTO>()
                .ForMember(dest => dest.CustId, opt => opt.MapFrom(src => src.CustomerId))
                .ForMember(dest => dest.CustData, opt => opt.MapFrom(src => src.CustName))
                .ForMember(dest => dest.CustomerJson, opt => opt.MapFrom(src => JsonConvert.DeserializeObject(src.CustomerJson));
            });
    }
}

主要

public class Program
{
    static void Main(string[] args)
    {
        var config = AppMapper.Mapping();
        var mapper = config.CreateMapper();

        // From Previous question get list of Customer objects
        var customers = AddCustomers();
        var mappedCustomers = mapper.Map<IEnumerable<CustomerTO>>(customers);
    }
}

要指出的一些事情 我不确定CustDataCustomerTO的目的是什么。它似乎是重复CustomerJson,如果是这样,请删除它和相关的映射。

此外,您从未提及从DTO到实体的映射,但对于JsonObject,您只需将其配置为将序列化字符串映射到相应的属性。

答案 1 :(得分:0)

这就是我满足要求的方式。

Db实体

public class Customer 
{
   public string CustomerData { get; set; }
   // & other properties 
}

我的DTO

public class CustomerTO
{
   public object CustomerData { get; set;}
   // & other properties
}

我创建了一个名为AppMapper的类实用工具。这就是我的AppMapper.cs的样子。

public class AppMapper
{
    private IMapper _mapper;
    public AppMapper()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Customer, CustomerTO>();
            //& other such mapping
        });

        _mapper = config.CreateMapper();
    }

public CustomerTO Map(Customer customerEntity)
    {
        var customerTo= _mapper.Map<Customer,CustomerTO>(customerEntity);
        return customerTo;
    }

现在我需要映射。

class DAL
{
    public CustomerTO GetCustomers()
    {
        var customers= //LINQ To get customers 

        var customerTO = Mapping(customer);

        return customerTO;

    }
    //However, this mapping glue in some internal class to retain SOLID principles
    private CustomerTO Mapping(Customer custEntity)
    {
        var custTO = _appMapper.Map(custEntity);
        var str = JsonConvert.Serialize(custTO.CustomerData);
        custTO.CustomerData = JsonConvert.Deserialize(str);
        return custTO;
    }
}

就是这样。

@Barry O'Kane - 真诚感谢您的投入。

要点: -

  1. 我不需要手动映射任何属性,因为属性名称相同。另外我正在将字符串转换为对象。所以没问题。
  2. 如果您对一个属性使用.Map(),那么我发现我需要映射每个属性,否则它会给出数据类型的默认值。(例如,对于int,它给出0)。
  3. 是。同意在Automapper中可能有其他方法允许我指定对于特定属性执行此手动映射&amp;休息使用自动机制。但我不确定。

    请随时以任何方式改进此问题。

    希望这会有所帮助:)