In this article, we will explore key techniques to ignore property in AutoMapper.

We will use the Ignore() method, the Ignore attribute, and the DoNotValidate() method. We will also discuss when and how to use each of the methods mentioned.

To download the source code for this article, you can visit our GitHub repository.

Without further ado, let’s start!

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

When to Ignore a Property in AutoMapper

Ignoring properties during mapping becomes crucial in scenarios where certain data fields are either irrelevant or we should not include them in the mapping process.

If you are new to AutoMapper or need a refresher, be sure to check our article Getting Started with AutoMapper in ASP.NET Core. This lays a solid foundation for understanding the concepts discussed here and their practical applications.

For example, our application may have complex domain objects we do not want to make available externally. Likewise, we may not want to return database objects to the client. To address this, we typically use Data Transfer Objects (DTOs).

Let’s illustrate this with a simple code example:

public class User
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public bool IsAdmin { get; set; }
    public DateTime CreatedAt { get; set; }
}

Here, we have a User class that corresponds to the database table. It contains properties considered as sensitive, such as Password and IsAdmin. Therefore, we don’t want to expose them. 

Using the Ignore Method to Ignore a Property in AutoMapper

The Ignore() method allows us to declare which properties should not be mapped, providing granular control over the mapping configuration. 

Let’s demonstrate the usage of the Ignore() method with a code example.

Firstly, we need to define a DTO object: 

public class UserDto
{
    public int Id { get; set; }
    public string Password { get; set; }
    public bool IsAdmin { get; set; }
    public DateTime CreatedAt { get; set; }
}

As already mentioned, we do not want the values of properties such as Password or IsAdmin to be passed to this object. For this reason, when creating the map, we must define which fields we want to ignore during the mapping:

var configuration = new MapperConfiguration(cfg =>
    cfg.CreateMap<User, UserDto>()
       .ForMember(dest => dest.Password, opt => opt.Ignore())
       .ForMember(dest => dest.IsAdmin, opt => opt.Ignore()));

Now all we need to do is create the mapper itself and perform the mapping:

var mapper = configuration.CreateMapper();
var userDto = mapper.Map<UserDto>(user);

The newly created DTO has all the properties set as in the User class, except Password and IsAdmin. Since AutoMapper didn’t map them, they have default values:

*** User ***
Id: 1
Email: [email protected]
Password: Password123!
IsAdmin: True
CreatedAt: 21.05.2024 21:01:13

*** UserDto ***
Id: 1
Password:
IsAdmin: False
CreatedAt: 21.05.2024 21:01:13

It is also worth mentioning that for library versions older than 8.0 ignoring properties is necessary when the destination object does not contain properties from the source object. Forgetting this will lead to an exception. The newer versions of the library allow us to avoid certain properties in the destination DTO and will not throw an error. 

Using Ignore Attribute to Ignore a Property in AutoMapper

As an alternative to the Fluent API, AutoMapper allows us to use attributes. To ignore a destination member we can simply add the Ignore attribute in the object class:

[AutoMap(typeof(User))]
public class UserDetailsDto
{
    public int Id { get; set; }
    public string Email { get; set; }
    [Ignore]
    public string Password { get; set; }
    [Ignore]
    public bool IsAdmin { get; set; }
    public DateTime CreatedAt { get; set; }
}

There are also a few additional differences from the definition using the Fluent API. First, we need to remember to mark the DTO with the AutoMap(typeof(User)) attribute. Thanks to this, we no longer need to create a configuration object.

Now we just need to create and use the mapper:

var configuration = new MapperConfiguration(cfg => cfg.AddMaps(typeof(Program).Assembly));
var mapper = configuration.CreateMapper();

var userDetailsDto = mapper.Map<UserDetailsDto>(user);

As a result, we will again obtain a DTO corresponding to the User class, omitting the properties marked with the Ignore attribute:

*** User ***
Id: 1
Email: [email protected]
Password: Password123!
IsAdmin: True
CreatedAt: 21.05.2024 21:01:13

*** UserDetailsDto ***
Id: 1
Email: [email protected]
Password:
IsAdmin: False
CreatedAt: 21.05.2024 21:01:13

How to Use DoNotValidate Method

With the introduction of newer versions of AutoMapper, the Ignore() method was renamed to DoNotValidate() for source members to avoid confusion. It’s worth noting that Ignore() remains valid, but now specifically for destination members. Therefore, while Ignore() persists for excluding destination properties, DoNotValidate() replaces it for source members in versions equal to or newer than 8.0.

As already mentioned, newer versions of the library do not throw errors when the destination DTO does not contain certain properties. This means that we no longer need to mark these source properties as ignored to ensure correct mapping.

However, AutoMapper includes an AssertConfigurationIsValid() method that allows us to check whether the mapping we have configured is correct. In this case, not including the property in the destination DTO still won’t cause an exception but can help us find properties that accidentally don’t have their equivalents in the mapped objects.

However, sometimes that’s exactly what we need. Therefore, to show the library that the properties were not omitted by mistake, we can use the DoNotValidate() method.

Let’s demonstrate this with a straightforward example:

public class UserDto
{
    public int Id { get; set; }
    public string Password { get; set; }
    public bool IsAdmin { get; set; }
    public DateTime CreatedAt { get; set; }
}

We update our UserDto class and remove the Email property.

Now we can create the mapping configuration and check if it’s valid: 

var configuration = new MapperConfiguration(cfg => 
    cfg.CreateMap<User, UserDto>(MemberList.Source));
configuration.AssertConfigurationIsValid();

The invocation of the AssertConfigurationIsValid() method will result in an exception. In this case, we can improve our configuration and use the DoNotValidate() method for the source object:

var configuration = new MapperConfiguration(cfg =>
    cfg.CreateMap<User, UserDto>(MemberList.Source)
       .ForSourceMember(source => source.Email, opt => opt.DoNotValidate()));

configuration.AssertConfigurationIsValid();

Conclusion

Effectively managing property exclusions in AutoMapper is essential knowledge while working with the library. By utilizing Ignore()  or IgnoreAttribute for destination members and DoNotValidate() for source members, developers can prevent unnecessary data transfer and improve mapping precision. 

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!