Question

Keeping this basic I have two models. customer and CustomerViewModel. I want to map the properties between one to another.

public class Customer
{
    public string CompanyName { get; set; }
    public int CustomerType { get; set; }
    public IEnumerable<ContactViewModel> CustomerContacts { get; set; }
}

public class CustomerViewModel
{
    public string CompanyName { get; set; }
    public int CustomerType { get; set; }
    public ContactName {get;set;}
    public ContactTel {get;set;}
}

The problem is I want to map customerContact to contactName and contactTel. I understand it is an IEnumerable and contains a list of contacts but during this filter IEnumerable of contact view model will only contain 1 record.

How would I do this type of mapping in automapper?

UPDATE:

I decided to go with a similar approuch someone mentioned earlier. I was hoping I can do this in automapper but I guess it is slightly more complex.

public static CustomerListViewModel MapToListView(this CustomerServiceModel svcModel)
    {
        ContactServiceModel contact = new ContactServiceModel { Name = String.Empty, Telephone = String.Empty }; 
        if(svcModel.CustomerContacts != null) contact = svcModel.CustomerContacts.FirstOrDefault();

        return new CustomerListViewModel
        {
            Id = svcModel.Id,
            address = svcModel.Address.MapToView(),
            CompanyName = svcModel.CompanyName,
            ContactName = contact.Name,
            ContactTelephone = contact.Telephone
        };
    }
Was it helpful?

Solution

I am not sure this can be done with AutoMapper. You can try to define an extension method, such as this:

public static CustomerViewModel ToViewModel(this Customer cust)
        {
            return new CustomerViewModel()
                {
                    CompanyName = cust.CompanyName,
                    CustomerType = cust.CustomerType,
                    ContactName = cust.CustomerContacts.First().ContactName,
                    ContactTel = cust.CustomerContacts.First().ContactTel
                };
        }

Of course, a little validation on top would be nice. Then you use it like this:

Customer cust= GetCustomer();
CustomerViewModel model= cust.ToViewModel();

OTHER TIPS

Try to use linq

public ActionResult Index()
{
   var viewmodel = CustomerViewModel();

   return View(viewmodel);
}

private static CustomerViewModel ()
{
    return new CustomerViewModel
    {
    ...
    ContactName = BusinessLogic.GetContactName("Microsoft");
    ContactTel = BusinessLogic.GetContactTel();
    }
}

Where BusinessLogic is your "brain"-class which decides what to get from data, and there use linq to get telephone and name:

public static class BusinessLogic
{
    public static string GetContactName(string companyName)
    {
        var c = new Customer () ... // get you Customer-object

        var q = (from contacts in c.CustomerContacts
                where contacts.CompanyName == companyName
                select contacts.ContactName).First();

        return q;
    }
}

But you have one mistake as I can see. You confuse view model-data (which you want to show for user on web-page) and model of data (which present object-model "Contacts"). In other words.. better to use special model class as Type for your CustomerContacts. Sorry for my "good" english. Hope I've helped you.

This will throw an exception if CustomerContacts is null or empty (I'll try to come up with a more robust solution), but here's something that would work for the happy path:

Mapper.CreateMap<Customer, CustomerViewModel>()
    .ForMember(dest => dest.ContactName, opt => opt.MapFrom(src => src.CustomerContacts.First().ContactName))
    .ForMember(dest => dest.ContactTel, opt => opt.MapFrom(src => src.CustomerContacts.First().ContactTel));

Perhaps a safer option would be to put the logic inside of the Customer class itself:

public class Customer
{
    /* other members */
    public string ContactName 
    { 
        get 
        {
            string name = null;
            if (CustomerContacts != null && CustomerContacts.Any()) 
            {
                name = CustomerContacts.First().ContactName;
            }

            return name;
        }
    }

    public string ContactTel
    {
        get 
        {
            string tel = null;


            if (CustomerContacts != null && CustomerContacts.Any()) 
            {
                tel = CustomerContacts.First().ContactTel;
            }
            return tel;
        }
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top