如何将AutoMapper与Post Action一起使用

时间:2012-05-22 10:55:11

标签: wcf asp.net-mvc-3 automapper self-tracking-entities

在我的解决方案中,我有一个ASP.NET MVC3项目,以及一个与数据库一起工作的WCF项目。 我使用entity framework self trackingAutoMapper来映射对象。

我的问题是:我如何使用AutoMapper与邮政行动一样使用箱子,删除和编辑方法

我看到这个Questions但不帮助我 这给了我一个错误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

1 个答案:

答案 0 :(得分:9)

您不应将Mapper.CreateMap放在控制器中,只需要执行一次该操作,因此请创建一个类似于此的引导程序,并从应用程序启动方法中调用它。

我认为这是您的错误来源:您只能创建一次映射。

哦,你正在定义错误的类型。你并没有试图将用户转换为MUser,但是你正在做相反的事情,所以它应该是:

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

如何执行此操作的示例:

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
    }
}

然后我有一个名为'Mappings'的项目,它包含bootstrap类和一些'配置'类(就像Entity Framework有EntityTypeConfiguration类,Ninject有NinjectModules):

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

和映射:

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));
    }
}

您可以按照自己喜欢的方式执行此操作,只需将所有映射放在Application_Start()方法中,但我发现这是一种干净且可维护的方式。