0

I have an EF6 MVC app using Code First to generate the models. I am trying to create a mapping using AutoMapper between the model and a view model representation of that model. However, when I do the mapping I receive the error:

Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.

I am definitely initializing the Mapper, but I am not able to figure out why the configuration is failing. Could anyone provide some assistance on what I can do to successfully use AutoMapper in this situation?

Here is the code for how I am configuring and initializing the Mapper:

    var pTConnections = _db.PTConnections.Include(p => p.PTConnectionClass).ToList();

        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<PTConnection, PTConnectionViewModel>()
                .AfterMap((s, d) => { foreach (var i in d.PTCredentialAssignments) i.PTConnection = d; });

            cfg.CreateMap<PTCredentialAssignment, PTCredentialAssignmentViewModel>()
                .ForMember(m => m.PTCredential, opt => opt.Ignore())
                .ForMember(m => m.PTConnection, opt => opt.Ignore());

            cfg.CreateMap<PTVendor, PTVendorViewModel>()
                .ForMember(m => m.PTCredentials, opt => opt.Ignore())
                .ForMember(m => m.PTConnections, opt => opt.Ignore());

            cfg.CreateMap<PTCredential, PTCredentialViewModel>();

            cfg.CreateMap<PTConnectionClass, PTConnectionClassViewModel>()
                .ForMember(m => m.PTConnections, opt => opt.Ignore());

            cfg.CreateMap<PTConnectionContactAssignment, PTConnectionContactAssignmentViewModel>()
                .ForMember(m => m.PTConnection, opt => opt.Ignore());

        });

    var dest = Mapper.Map<List<PTConnection>, List<PTConnectionViewModel>>(pTConnections);

Here is my Code First Model:

public partial class PTConnection
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public PTConnection()
    {
        PTConnectionAssignments = new HashSet<PTConnectionAssignment>();
        PTCredentialAssignments = new HashSet<PTCredentialAssignment>();
        PTConnectionContactAssignments = new HashSet<PTConnectionContactAssignment>();
    }

    [Key]
    public int PTCID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(255)]
    public string ConnectionName { get; set; }

    [Required]
    [StringLength(100)]
    public string Host { get; set; }

    public int Port { get; set; }

    public string Comment { get; set; }

    public int PTCCID { get; set; }

    public bool? IsDisabled { get; set; }

    public int PTVID { get; set; }

    public virtual PTConnectionClass PTConnectionClass { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTConnectionAssignment> PTConnectionAssignments { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTCredentialAssignment> PTCredentialAssignments { get; set; }

    public virtual PTVendor PTVendor { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTConnectionContactAssignment> PTConnectionContactAssignments { get; set; }
}

public partial class PTCredential
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public PTCredential()
    {
        PTCredentialAssignments = new HashSet<PTCredentialAssignment>();
        PTCredentialContactAssignments = new HashSet<PTCredentialContactAssignment>();
    }

    [Key]
    public int PTCRID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(100)]
    public string CredUsername { get; set; }

    [Required]
    [StringLength(500)]
    public string CredPassword { get; set; }

    public string Directory { get; set; }

    public bool? IsDisabled { get; set; }

    public string Comments { get; set; }

    public int? PTVID { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTCredentialAssignment> PTCredentialAssignments { get; set; }

    public virtual PTVendor PTVendor { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTCredentialContactAssignment> PTCredentialContactAssignments { get; set; }
}

public partial class PTVendor
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public PTVendor()
    {
        PTConnections = new HashSet<PTConnection>();
        PTCredentials = new HashSet<PTCredential>();
        PTIneligableCredentialVendorAssignments = new HashSet<PTIneligableCredentialVendorAssignment>();
        PTVendorAssignments = new HashSet<PTVendorAssignment>();
        PTVendorContactAssignments = new HashSet<PTVendorContactAssignment>();
    }

    [Key]
    public int PTVID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(50), Display(Name="Vendor Name")]
    public string Name { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTConnection> PTConnections { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTCredential> PTCredentials { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTIneligableCredentialVendorAssignment> PTIneligableCredentialVendorAssignments { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTVendorAssignment> PTVendorAssignments { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTVendorContactAssignment> PTVendorContactAssignments { get; set; }
}

[Table("PTCredentialAssignment")]
public partial class PTCredentialAssignment
{
    [Key]
    public int PTCRAID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    public int PTCID { get; set; }

    public int PTCRID { get; set; }

    public virtual PTConnection PTConnection { get; set; }

    public virtual PTCredential PTCredential { get; set; }
}

[Table("PTConnectionClass")]
public partial class PTConnectionClass
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public PTConnectionClass()
    {
        PTConnections = new HashSet<PTConnection>();
    }

    [Key]
    public int PTCCID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(50)]
    public string Class { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PTConnection> PTConnections { get; set; }
}

[Table("PTConnectionContactAssignment")]
public partial class PTConnectionContactAssignment
{
    [Key]
    public int PTCCAID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    public int PTCID { get; set; }

    [Required]
    [StringLength(60)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(60)]
    public string LastName { get; set; }

    [Required]
    [StringLength(10)]
    public string PhoneNumber { get; set; }

    [StringLength(20)]
    public string Extension { get; set; }

    [StringLength(100)]
    public string Email { get; set; }

    [StringLength(60)]
    public string Title { get; set; }

    public string Comment { get; set; }

    public virtual PTConnection PTConnection { get; set; }
}

Here is my ViewModel:

   public partial class PTConnectionViewModel
    {
        [Key]
        public int PTCID { get; set; }

        [Column(TypeName = "datetime2")]
        public DateTime ModifiedDate { get; set; }

        [Required]
        [StringLength(500)]
        public string ModifiedBy { get; set; }

        [Required]
        [StringLength(255)]
        public string ConnectionName { get; set; }

        [Required]
        [StringLength(100)]
        public string Host { get; set; }

        public int Port { get; set; }

        public string Comment { get; set; }

        public int PTCCID { get; set; }

        public bool? IsDisabled { get; set; }

        public int PTVID { get; set; }

        public virtual PTConnectionClassViewModel PTConnectionClass { get; set; }

        public virtual ICollection<PTConnectionAssignmentViewModel> PTConnectionAssignments { get; set; }

        public virtual ICollection<PTCredentialAssignmentViewModel> PTCredentialAssignments { get; set; }

        public virtual PTVendorViewModel PTVendor { get; set; }

        public virtual ICollection<PTConnectionContactAssignmentViewModel> PTConnectionContactAssignments { get; set; }
    }

public partial class PTVendorViewModel
{
    [Key]
    public int PTVID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(50), Display(Name="Vendor Name")]
    public string Name { get; set; }

    public virtual ICollection<PTConnectionViewModel> PTConnections { get; set; }

    public virtual ICollection<PTCredentialViewModel> PTCredentials { get; set; }

}

public partial class PTCredentialViewModel
{
    [Key]
    public int PTCRID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(100)]
    public string CredUsername { get; set; }

    [Required]
    [StringLength(500)]
    public string CredPassword { get; set; }

    public string Directory { get; set; }

    public bool? IsDisabled { get; set; }

    public string Comments { get; set; }

    public int? PTVID { get; set; }

    public virtual ICollection<PTCredentialAssignmentViewModel> PTCredentialAssignments { get; set; }

    public virtual PTVendorViewModel PTVendor { get; set; }

    public virtual ICollection<PTCredentialContactAssignmentViewModel> PTCredentialContactAssignments { get; set; }
}

public partial class PTCredentialAssignmentViewModel
{
    [Key]
    public int PTCRAID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    public int PTCID { get; set; }

    public int PTCRID { get; set; }

    public virtual PTConnectionViewModel PTConnection { get; set; }

    public virtual PTCredentialViewModel PTCredential { get; set; }
}

public partial class PTConnectionClassViewModel
{

    [Key]
    public int PTCCID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    [Required]
    [StringLength(50)]
    public string Class { get; set; }

    public virtual ICollection<PTConnectionViewModel> PTConnections { get; set; }
}

public partial class PTConnectionContactAssignmentViewModel
{
    [Key]
    public int PTCCAID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime ModifiedDate { get; set; }

    [Required]
    [StringLength(500)]
    public string ModifiedBy { get; set; }

    public int PTCID { get; set; }

    [Required]
    [StringLength(60)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(60)]
    public string LastName { get; set; }

    [Required]
    [StringLength(10)]
    public string PhoneNumber { get; set; }

    [StringLength(20)]
    public string Extension { get; set; }

    [StringLength(100)]
    public string Email { get; set; }

    [StringLength(60)]
    public string Title { get; set; }

    public string Comment { get; set; }

    public virtual PTConnectionViewModel PTConnection { get; set; }
}
  • @Amy, I made the modifications you suggested, however I get a new error now: _"Error mapping types. \r\n\r\nMapping types:\r\nList`1 -> List`1\r\nSystem.Collections.Generic.List`1[[PTApp.Models.PTConnection, PTApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.List`1[[PTApp.ViewModels.PTConnectionViewModel, PTApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}_ – silverbullettruck2001 Sep 09 '16 at 18:45
  • That's because each property type also needs to be mapped. It doesn't know how to map each property, for example `PTConnectionClass ` needs to be mapped to `PTConnectionClassViewModel `. Once all the property types are mapped you can map the main objects. –  Sep 09 '16 at 19:05
  • Furthermore, if you expand that exception and inspect the inner exception, it will tell you which property it can't map. –  Sep 09 '16 at 19:08
  • @Amy, I added the mappings but now it is telling me that there is a Stack Overflow Exception. Any thoughts on what would cause this? Thanks again for your assistance. – silverbullettruck2001 Sep 09 '16 at 20:35
  • Yeah, you're now (auto)mapping objects (yay!), but you have a circular reference somewhere. Those can be tricky. I'd suggest googling "automapper circular reference". –  Sep 09 '16 at 21:11
  • **Thanks** @Amy! I was able to get around the circular references by using some ignore methods on the offending properties (post updated). I don't have errors, but the resulting object is missing details for the PTCredential object. Specifically I am missing the PTCredential object that is nested within a PTCredential. I don't believe the Ignores are causing this, but I can't pin it down. I have tried some suggestions from other posts on AM, but nothing has proven useful. Any suggestions on how to get it included? – silverbullettruck2001 Sep 12 '16 at 17:15
  • I'd ask a new question with your mapping code and the gist of your models. –  Sep 12 '16 at 17:28

1 Answers1

5

Just create the map from one type to another. Don't create the map from a List of one type to a list of another type. Automapper can automatically handle collections.

In effect, you're telling Automapper how to map a List<A> to a List<B> without telling Automapper how to actually map A to B. Change your registration to the following:

Mapper.Initialize(cfg => 
{
    cfg.CreateMap<PTConnection, PTConnectionViewModel>();
});

You can still map a List<PTConnection> to a List<PTConnectionViewModel> just fine, as well as most other collection types.