How to ignore null values for all source members during mapping in Automapper 6?
Method Condition
now has five overloads, one of which accepts predicate of type
Func<TSource, TDestination, TMember, bool>
this TMember parameter is the source member. So you can check source member for null:
CreateMap<StatusLevelDTO, StatusLevel>()
.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));
AutoMapper.Map ignore all Null value properties from source object
Interesting, but your original attempt should be the way to go. Below test is green:
using AutoMapper;
using NUnit.Framework;
namespace Tests.UI
{
[TestFixture]
class AutomapperTests
{
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int? Foo { get; set; }
}
[Test]
public void TestNullIgnore()
{
Mapper.CreateMap<Person, Person>()
.ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));
var sourcePerson = new Person
{
FirstName = "Bill",
LastName = "Gates",
Foo = null
};
var destinationPerson = new Person
{
FirstName = "",
LastName = "",
Foo = 1
};
Mapper.Map(sourcePerson, destinationPerson);
Assert.That(destinationPerson,Is.Not.Null);
Assert.That(destinationPerson.Foo,Is.EqualTo(1));
}
}
}
MapAutomapper ignore Null values
Change your code to this:
var ot = mapper.Map(thing1, thing2);
so you will define source and target objects, and they will be merged.
Skip mapping null properties
The easy way would be to not have to distinguish between null and Guid.Empty
. Like this
cfg.CreateMap<Source, Destination>()
.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => ((Guid)srcMember) != Guid.Empty));
In this case the source member is not the string value you map from, it's the resolved value that would be assigned to the destination. It's of type Guid
, a struct, so it will never be null. A null string will map to Guid.Empty
. See here.
How to configure Automapper to ignore Object-Properties if properties is null but map if not null
You can specify a custom resolver to explicitly do your custom mapping.
CreateMap<PersonDTO, Person>()
.ForMember(dest => dest.UserDetails, opt => opt.MapFrom<CustomResolver>());
public class CustomResolver : IValueResolver<PersonDTO, Person, UserProperties>
{
public UserProperties Resolve(PersonDTO source, Person destination, UserProperties member, ResolutionContext context)
{
if (source.UserId == 0)
return null;
return new UserProperties
{
DisplayName = source.UserName,
Id = source.UserId
};
}
}
AutoMapper configure to ignore null source member to custom struct type destination member
In AutoMapper, when a destination object is created using service locator, it treats the initial destination as null, and maps all the members using the default value default(MyStruct)
when UseDestinationValue
is not configured for the member, as written in the source code.
The solution would be to configure .UseDestinationValue()
on the member mapping expression.
In my case, there are many models having members that should be mapped from decimal?
to MyStruct
, so I have an extension method instead.
public static IMappingExpression<TSource, TDestination> UseDestinationValueForKnownMemberTypes<TSource, TDestination>(this IMappingExpression<TSource, TDestination> mappingExpression)
{
mappingExpression.ForAllMembers(options =>
{
if (IsKnownType(options.DestinationMember))
{
options.UseDestinationValue();
}
});
return mappingExpression;
}
private static bool IsKnownType(MemberInfo destinationMember)
{
var propertyType = destinationMember is PropertyInfo p ? p.PropertyType : null;
// Use a static hashset to handle multiple types
return propertyType == typeof(MyStruct);
}
CreateMap<Source, IDestination>()
.UseDestinationValueForKnownMemberTypes();
C# Automapper Ignore Property When Null
Try this:
Mapper.CreateMap<AccountEditViewModel, User>()
.ForMember(model => model.Password, model => model.Ignore())
.AfterMap((src, dst) =>
{
if (src.Password != null)
dst.Password= EncryptPassword(src.Password);
});
Related Topics
Calling a Generic Method with a Dynamic Type
Remove Text In-Between Delimiters in a String (Using a Regex)
Get a Generic Method Without Using Getmethods
Replacing a Char at a Given Index in String
Wpf C# Path: How to Get from a String with Path Data to Geometry in Code (Not in Xaml)
Creating Composite Key Entity Framework
Lambda Expression Using Foreach Clause
Generic Base Class for Winform Usercontrol
Why C# Is Not Allowing Non-Member Functions Like C++
How to Execute Process Commands (Or Similar) Using a Universal Windows Platform (Uwp) App
Can't Convert Value Type Array to Params Object[]
Loading a Full Hierarchy from a Self Referencing Table with Entityframework.Core
Force Xmlserializer to Serialize Datetime as 'Yyyy-Mm-Dd Hh:Mm:Ss'
Does Stream.Dispose Always Call Stream.Close (And Stream.Flush)