Search code examples
c#dictionaryautomapper

AutoMapper - Map object properties to dictionary


I am trying to map an object to a dictionary in a way that each property will be a dictionary item.

Object with id and name -> dictionary with two items containing property name and value.

I know it is a simple thing, but I was not able to find a solution for it. Maybe it is something I am not understanding...

I receive the following error:

Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
=======================================================================================================================================================================================================================================================================
Book -> Dictionary`2 (Destination member list)
Book -> System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] (Destination member list)

Unmapped properties:
Keys
Values
Item

In the following code you can see my implementation:

using AutoMapper;

var book = new Book()
{
    Id = 1,
    Name = "A"
};

IMapper mapper = new Mapper(new MapperConfiguration(
    config => config.CreateMap<Book, Dictionary<string, string>>()
        .ConstructUsing((source, dest) => new Dictionary<string, string>()
        {
            { "id", source.Id.ToString() },
            {"name", source.Name}
        })));

mapper.ConfigurationProvider.AssertConfigurationIsValid();

var bookData = new Dictionary<string, string>();

mapper.Map(book, bookData);

public class Book
{
    public int Id { get; set; }

    public string Name { get; set; }
}

Solution

  • As @Lucian mentioned in a comment, Automapper has built-in methods to convert object from/to dynamic, Dictionary<string, object>.

    However, I think that there is an issue if you implement a converter to Dictionary<string, string>.

    Hence, it is better to build a custom implementation for the conversion as below:

    using System.Reflection;
    using Newtonsoft.Json;
    
    public static class DictionaryExtensions
    {
        public static Dictionary<string, string> ToDictionary<T>(this T src) where T : new()
        {
            Dictionary<string, string> result = new ();
            
            PropertyInfo[] properties = typeof(T).GetProperties();
                    
            foreach (PropertyInfo prop in properties)
            {           
                result.Add(prop.Name, prop.PropertyType == typeof(string)
                           ? prop.GetValue(src)?.ToString()
                           : JsonConvert.SerializeObject(prop.GetValue(src)));
            }
            
            return result;
        }
    }
    

    For caller:

    var bookData = book.ToDictionary();
    

    Demo @ .NET Fiddle