When I try to map an object that has a null string property, the destination is also null. Is there a global settings I can turn on that says all null string should be mapped to empty?
Something like this should work:
public class NullStringConverter : ITypeConverter<string, string>
{
public string Convert(string source)
{
return source ?? string.Empty;
}
}
And in your configuration class:
public class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.CreateMap<string, string>().ConvertUsing<NullStringConverter>();
Mapper.AddProfile(new SomeViewModelMapper());
Mapper.AddProfile(new SomeOtherViewModelMapper());
...
}
}
If you need a non-global setting, and want to do it per property:
Mapper.CreateMap<X, Y>()
.ForMember(
dest => dest.FieldA,
opt => opt.NullSubstitute(string.Empty)
);
Similar to David Wick's answer, you can also use ConvertUsing
with a lambda expression, which eliminates the requirement for an additional class.
Mapper.CreateMap<string, string>().ConvertUsing(s => s ?? string.Empty);
I'm using EF Reverse Engineering and it has a nasty habit of defining
string Name { get; set; } = null!;
The null on a non-nullable string causes many headaches. Finally, I added this mapping function and created "ghost" intermediate objects to absorb the mapping.
/// <inheritdoc />
[PublicAPI]
internal class MapperProfile<TSrcType, TDstType> : Profile
where TSrcType : class
where TDstType : class, new()
{
public MapperProfile()
{
CreateMap<TSrcType, TDstType>(MemberList.None)
.ConvertUsing((src, dst) =>
{
ArgumentNullException.ThrowIfNull(src);
dst ??= new TDstType();
var dstType = dst.GetType()!;
var srcType = src.GetType()!;
foreach (var dstInfo in dstType.GetProperties()
.Where(x => x.CanWrite)
.Select(x => dstType.GetProperty(x.Name)!))
{
var srcInfo = srcType.GetProperties()
.SingleOrDefault(info => info.Name == dstType.Name && info.CanRead);
try
{
var value = (srcInfo is not null)
? srcInfo.GetValue(src, null)
: dstInfo.CanRead
? dstInfo.GetValue(dst, null)
: dstInfo.PropertyType.IsValueType
? Activator.CreateInstance(dstInfo.PropertyType)
: null; // I give up..., anyone have an idea?
if (dstInfo.PropertyType == typeof(string))
value ??= string.Empty;
dstInfo.SetValue(dst, value);
}
catch (Exception e)
{
Trace.WriteLine(e);
Debugger.Break();
}
}
return dst;
});
}
}
You may wish to further qualify which strings get remapped. I used the NotNullAttribute
, and I had control of the sources so adding it to those strings that I wanted to insure non-null-ness was fairly easy.
© 2022 - 2024 — McMap. All rights reserved.
Mapper.AddProfile(new SomeViewModelMapper());
? Is this something where I can add multiple mappers? – Formative