سؤال

I have an Item that contains a list of Product's which are mapped to their respective ViewModel objects using AutoMapper.

In my MVC project I have an Action method that displays an Item with a selected Product. For this i have a ViewModel called ItemDetailsViewModel that contains the flattened Item object, a list of ProductViewModel's and a flattened selected Product.

The difficulty I am having is best showing this flattened selected Product.

Think of it like eBay where you have an Item and you can choose multiple variations e.g. by colour. For me, the multiple variations are the Products. When the user selects the Product I want to return the ItemDetails i.e. the Item, the list of Products and the selected Product.

I was wondering the best way of doing this? At the moment my method is mapping an Item to an ItemDetailsViewModel, selecting the desired ProductViewModel and then specifically mapping each property of the ProductViewModel back onto the ItemDetailsViewModel. Also, due to the Item and Product having the same named properties, the last line mapping the product back overwrites the Items id and code.

Any suggestions on how best to configure the mapping?

I've left out the mapping I have in place as it is mostly a direct one-to-one mapping apart from mapping the selected ProductViewModel back to the ItemDetailsViewModel.

Mapper.CreateMap<Item, ItemViewModel>()
    .ReverseMap();

Mapper.CreateMap<ProductViewModel, ItemDetailsViewModel>()
    .ForMember(d => d.ProductId, o => o.MapFrom(s => s.Id))
    .ForMember(d => d.ProductCode, o => o.MapFrom(s => s.Code));

Classes

public class Item
{
    public int Id { get; set; }
    public string Code { get; set; }
    public IList<Product> Products { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Code { get; set; }
}

public class ItemViewModel
{
    public int Id { get; set; }
    public string Code { get; set; }

    public IList<ProductViewModel> Products { get; set; }
}

public class ItemDetailsViewModel : ItemViewModel
{
    public int ProductId;
    public string ProductCode;
}

public class ProductViewModel
{
    public int Id { get; set; }
    public string Code { get; set; }
}

Action

public ActionResult ItemDetails()
{
    var item = new Item
    {
        Id = 1,
        Code = "Item1",
        Products = new List<Product>()
        {
            new Product { Id = 1, Code = "Product1" },
            new Product { Id = 2, Code = "Product2" },
            new Product { Id = 3, Code = "Product3" },
        }
    };

    var productCode = "Product2";
    var itemDetailsViewModel = Mapper.Map<ItemDetailsViewModel>(item);

    if (itemDetailsViewModel.Products != null && itemDetailsViewModel.Products.Count > 0)
    {
        ProductViewModel productViewModel = null;
        if (!String.IsNullOrEmpty(productCode))
            productViewModel = itemViewModel.Products.FirstOrDefault(e => e.Code.Equals(productCode, StringComparison.OrdinalIgnoreCase));

        if (productViewModel == null)
            productViewModel = itemViewModel.Products[0];

        Mapper.Map<ProductViewModel, ItemDetailsViewModel>(productViewModel, itemDetailsViewModel);
    }
}
هل كانت مفيدة؟

المحلول

One solution would be to ignore the properties in ItemDetailsViewModel in your mapping from ProductViewModel to ItemDetailsViewModel:

Mapper.CreateMap<ProductViewModel, ItemDetailsViewModel>()
    .ForMember(d => d.Id, opt => opt.Ignore())
    .ForMember(d => d.Code, opt => opt.Ignore())
    .ForMember(d => d.ProductId, o => o.MapFrom(s => s.Id))
    .ForMember(d => d.ProductCode, o => o.MapFrom(s => s.Code));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top