Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper.AutoMapperMappingException: Type 'System.String' does not have a default constructor

Tags:

c#

automapper

A strange error began occurring in our code in the lest week or two. I am trying to identify the root cause of the mapping failure. The most-inner exception itself is puzzling: Type 'System.String' does not have a default constructor

I don't understand what the exception is telling me. Can you explain what has happened and maybe how I could resolve this bug?

The mapper is used within a generic method:

public TEntity UpdateWithHistory<TEntity>(TEntity entity, int? entityID, int? interviewID)
where TEntity : class
{
    var snapshot = _interviewContext.Find<TEntity>(entityID);

    // This is call that fails
    var history = Mapper.Map<TEntity, TEntity>(snapshot);

    _interviewHistory.Set<TEntity>().Add(history);
    MarkModified(entity);
    return Mapper.Map(entity, snapshot);
}

In the above code, snapshot is NOT null. The full exception:

AutoMapper.AutoMapperMappingException:
Trying to map Recog.Web.Models.InterviewComment to Recog.Web.Models.InterviewComment.
Using mapping configuration for Recog.Web.Models.InterviewComment to Recog.Web.Models.InterviewComment
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
  ---> AutoMapper.AutoMapperMappingException: Trying to map System.String to System.String.
       Using mapping configuration for System.String to System.String
       Destination property: Comment
       Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
  ---> AutoMapper.AutoMapperMappingException: Trying to map System.String to System.String.
       Using mapping configuration for System.String to System.String
       Destination property: Comment
       Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
  ---> System.ArgumentException: Type 'System.String' does not have a default constructor
     at System.Linq.Expressions.Expression.New(Type type)
     at AutoMapper.DelegateFactory.CreateCtor(Type type)
     at AutoMapper.Mappers.ObjectCreator.CreateObject(Type type)
     at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.CreateObject(ResolutionContext context)
     at AutoMapper.Mappers.TypeMapObjectMapperRegistry.NewObjectPropertyMapMappingStrategy.GetMappedObject(ResolutionContext context, IMappingEngineRunner mapper)
     at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper)
     at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
     at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
     --- End of inner exception stack trace ---
     at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
     at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap)
     --- End

The Comment class that is mentioned:

public class InterviewComment
{
    [Key]
    public int? InterviewCommentID { get; set; }

    [ForeignKey("Interview")]
    public int? InterviewID { get; set; }

    [CodeType(CodeTypeEnum.CommentSection)]
    public int? CommentSectionCodeID { get; set; }

    [CodeType(CodeTypeEnum.CommentSource)]
    public int? CommentSourceCodeID { get; set; }

    [Display(Name = "Comment")]
    [StringLength(int.MaxValue)]
    public string Comment { get; set; }

    [Include]
    [Association("Interview_1-*_InterviewComment", "InterviewID", "InterviewID", IsForeignKey = true)]
    public virtual Interview Interview { get; set; }

    [ReadOnly(true)]
    [ForeignKey("ModifiedByUser")]
    public virtual ApplicationUser ApplicationUser { get; set; }

    [ReadOnly(true)]
    public string UserName
    {
        get { return ApplicationUser != null ? ApplicationUser.GetDisplayName() : null; }
    }

    [ReadOnly(true)]
    public int CreatedByUser { get; set; }

    [ReadOnly(true)]
    public DateTime CreatedDateTime { get; set; }

    [ReadOnly(true)]
    public int ModifiedByUser { get; set; }

    [ReadOnly(true)]
    public DateTime ModifiedDateTime { get; set; }
}

I'm still reviewing recent commits to identify the change that is causing this. Any insight into the exception would be greatly appreciated.

like image 316
Ed Chapel Avatar asked Jun 06 '11 15:06

Ed Chapel


1 Answers

The root cause of the error was in code that was not shared. We have a convention that configured mappings for specific types discovered through reflection. Our algorithm incorrectly created a map for string, replacing the default mapping provided by AutoMapper.

Should you ever see the error Type 'System.String' does not have a default constructor, confirm your code does not create a map for string.

like image 144
Ed Chapel Avatar answered Sep 27 '22 17:09

Ed Chapel