Click here to Skip to main content
14,601,122 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hi guys good day,

I'm developing a new MVC site for my company & kind of confused as how to create mapping from Domain/POCO objects to ViewModel classes [contains validation] & vice versa. Here's an sample example.

My domain class:
public partial class Glossary
    {
        public int Id { get; set; }
        public string GlossaryItem { get; set; }
        public string Definition { get; set; }
    }


my ViewModel class:
public class GlossaryModel
    {
        [HiddenInput(DisplayValue = false)]
        public int Id { get; set; }

        [Required(ErrorMessage = "Please enter a GlossaryItem")]
        public string GlossaryItem { get; set; }

        [Required(ErrorMessage = "Please enter a Definition")]
        public string Definition { get; set; }
    }


my Automapper configuration for DTO to Domain Model:
protected override void Configure()
    {
         CreateMap<GlossaryModel, Glossary>();
         //....... etc
    }


My controller's action method:
public class GlossaryController : Controller
{
    IGlossaryRepository _glossaryRepository;
    IMappingService _mappingService;

    public GlossaryController(IGlossaryRepository glossaryRepository, IMappingService autoMapperMappingService)
    {
        _glossaryRepository = glossaryRepository;
        _mappingService = autoMapperMappingService;
    }

    // .... etc

    [HttpPost, ValidateAntiForgeryToken]
    public virtual ActionResult Edit(GlossaryModel glossaryModel)
    {
        if (ModelState.IsValid)
        {
            var glossary = _mappingService.Map<GlossaryModel, Glossary>(glossaryModel);
            if (glossaryModel.Id <= 0)
                _glossaryRepository.Add(glossary);
            else
                _glossaryRepository.Edit(glossary);
            _glossaryRepository.Save();
            TempData["message"] = string.Format("{0} has been saved", glossaryModel.Definition);
            return RedirectToAction("All");
        }
        return View(glossaryModel);
    }

    //....etc
 }


And it's working fine, but my question is... Now say I need an action that will list down all glossary items like
public ActionResult All()
        {
            var allItems = _glossaryRepository.Glossary;
            if (allItems.Count() == 0) return View(new List<GlossaryModel>());
            var allItemsModel = _mappingService.Map<IEnumerable<Glossary>, IEnumerable<GlossaryModel>>(allItems);
            return View(allItemsModel);
        }

But now I need automapper to convert from Domain objects to DTO [from List(Glossary) to List(GlossaryModel)], just opposite of the Edit method, to push the data to the view. So do I again need to map the opposite binding in the automapper config...!! like
protected override void Configure()
    {
         CreateMap<GlossaryModel, Glossary>(); // Added before for DTO to Domain object 
         CreateMap<Glossary, GlossaryModel>();// Added for Domain object to DTO
         //....... etc
    }


Is it a good design to bind both ways? or there's better solution I'm missing, Please help

Thanks,
Sanjay
Posted

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

Hi,

There is no issue with your code but if you need to minimize you code then try this,

CreateMap<Source, Dest>().BothWays();


[Update]

Few Articles you may enjoy :

http://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/[^]

http://bengtbe.com/blog/2009/04/14/using-automapper-to-map-view-models-in-asp-net-mvc/[^]

http://prashantbrall.wordpress.com/2010/11/02/automapper/[^]
   
v2
Comments
Sanjay Debnath 9-Jan-13 7:23am
   
Bothways doesn't exist by default... You need to write an extersion method for that like

public static IMappingExpression<TDestination, TSource> BothWays<tsource, tdestination="">
(this IMappingExpression<tsource, tdestination=""> mappingExpression)
{
return Mapper.CreateMap<TDestination, TSource>();
}

Also it can be achieved by the builtin .ReverseMap() in the map chain.
Suvabrata Roy 9-Jan-13 7:32am
   
Yes...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100