5

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.

2
  • 2
    Dumb question: does AutoMapper's Mapper.AssertConfigurationIsValid() tell you anything? Commented Jun 6, 2011 at 16:02
  • Good idea and I had not thought to try it. However, the config is indeed valid. Commented Jun 6, 2011 at 16:43

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is not good enough. How to map an object to a string then?
2

String does not have a default constructor, which wouldn't be usefull anyway as a string is immutable.

To narrow down your problem, what data is supplied to the method. What data are you trying to map. What's the value of the Comment property in the item you're trying to map?

4 Comments

An instance of InterviewComment with Comment = "Foo" is passed as entity. Also, snapshot is an instance of InterviewComment coming from the database using EF Code First where Comment = "Bar".
Hmmm in that case I'm lost too. The only thing I can think of is, what happens if you create a non EF class and see what happens? Shouldn't make a difference but worth the test I guess
Have you tried mapping an entity which did not come from your context (excluding that as a problem).
I did map from a non-proxy item. That entity had a null string and did not suffer the same error. However, it led to the ultimate discovery.
2

I had same error. I wanted to map array of objects to array of objects

This generated error

AutoMapper.AutoMapperMappingException: Type 'TargetObjectType'

does not have a default constructor:

AutoMapper.Mapper.CreateMap<SourceObjectType[], TargetObjectType[]>();
TargetObject = AutoMapper.Mapper.Map<SourceObjectType[], TargetObjectType[]>(SourceObject);

When I set correctly types for mapping, then error dissapeared.

AutoMapper.Mapper.CreateMap<SourceObjectType, TargetObjectType>();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.