Question

in my solution I have an ASP.NET MVC3 project, and a WCF project that works with a database. I use entity framework self tracking and AutoMapper to map objects.

My question is: how i can use AutoMapper with Post Action like crate and delete and Edit methods

i see this Questions but not help me this give me an error argument type '...' is not assignable to parameter type '...'

      [HttpPost]
      public ActionResult Create(MUser muser)
      {
        if (ModelState.IsValid)
        {
            Mapper.CreateMap<User, MUser>();
            var user = Mapper.Map<User, MUser>(muser);
            _proxy.SaveUser(user);
            return RedirectToAction("Index");

        }
        return View(muser);
      }

enter image description here

Was it helpful?

Solution

You shouldn't place the Mapper.CreateMap in your controller, you need to perform that action only once, so create a bootstrapper or something like that and call it from your application start method.

I think that's where your error comes from: you can create a mapping only once.

Oh, and you're defining the wrong types. You aren't trying to convert a User to a MUser, but you're doing it the other way around, so it should be:

Mapper.CreateMap<MUser, User>();
Mapper.Map<MUser, User>(muser);

Example of how to do this:

public class MvcApplication : HttpApplication
{
    // some methods

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        MappingsBootstrapper.Initialize(); // call the bootstrap class that I created
    }
}

Then I've got a project called 'Mappings' and it contains the bootstrap class and some 'configuration' classes (just like Entity Framework has EntityTypeConfiguration classes and Ninject has NinjectModules):

public static class MappingsBootstrapper
{
    public static void Initialize()
    {
        new UserMappings();
        new BookcaseItemMappings();
    }
}

And the mappings:

class UserMappings
{
    public UserMappings()
    {
        Mapper.CreateMap<User, UserSetupViewModel>();
        Mapper.CreateMap<UserSetupViewModel, User>();
    }
}

class BookcaseItemMappings
{
    public BookcaseItemMappings()
    {
        Mapper.CreateMap<NewBookViewModel, BookcaseItem>().ForMember(x => x.BookId, opt => opt.Ignore());
        Mapper.CreateMap<BookcaseItem, BookcaseItemViewModel>()
            .ForMember(x => x.Title, opt => opt.MapFrom(src => src.Book.Title))
            .ForMember(x => x.Authors, opt => opt.MapFrom(src => src.Book.Authors.Select(x => x.Name).Aggregate((i, j) => i + ", " + j)))
            .ForMember(x => x.Identifiers, opt => opt.MapFrom(src => (!string.IsNullOrEmpty(src.Book.Isbn10) ? ("ISBN10: " + src.Book.Isbn10 + "\r\n") : string.Empty) +
                                                                     (!string.IsNullOrEmpty(src.Book.Isbn13) ? ("ISBN13: " + src.Book.Isbn13) : string.Empty)))
            .ForMember(x => x.Pages, opt => opt.MapFrom(src => src.Book.Pages))
            .ForMember(x => x.ImageUri, opt => opt.MapFrom(src => src.Book.ThumbnailUriSmall));
    }
}

You can do it any way you like, you could just place all the mappings in your Application_Start() method, but I found this to be a clean and maintainable way.

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