简体   繁体   中英

Automapper If source is null, set destination object properties

I have the following case:

Source :

public class AccountLogin
{
    public int UserID { get; set; }

    public bool AccountVerified { get; set; }
}

This object is returned from the database, so if no user is found it could be null

Destination :

public class LoginUserResponseModel
{
    public bool AccountExists { get; set; }
    public bool AccountVerified { get; set; }
    public string Status { get; set; }
    public string Token { get; set; }
}

What do I need?
If the source is null, I need an instance of the destination object with the following parameters:

{
    "AccountExists": false,
    "AccountVerified": false
    "Status": "Error"
    "Token": null
}

The AutoMapper code I put into my MappingProfile.cs file is as follows:

 CreateMap<AccountLogin, LoginUserResponseModel>()
     .ForMember(dest => dest.AccountExists, opt => opt.MapFrom(src => src == null ? false : true))
     .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src == null ? "Error" : "Ok"));

This code works fine when the object is not null, it sets Status = "Ok" and AccountExists = false

When I have received existing user from the database, my source, AccountLogin , eg: 在此处输入图片说明

So this maps correctly like this: 在此处输入图片说明

The problem is when the source is null, the destination is also null:

在此处输入图片说明

I have a lot of workarounds, but I am really curious if this could be made with AutoMapper .
The project I am using is ASP Net Core 2.2 and AutoMapper v6.1.1

In response to your comments I would suggest using a CustomTypeConverter: http://docs.automapper.org/en/stable/Custom-type-converters.html

public class AccountLoginConverter : ITypeConverter<AccountLogin, LoginUserResponseModel>
{
    public LoginUserResponseModel Convert(AccountLogin source, LoginUserResponseModel destination, ResolutionContext context)
    {
        if(source == null)
        {
            return new LoginUserResponseModel { AccountExists = false, Status = "Error" }
        }

        // You can have more complex logic here      

        return new LoginUserResponseModel
        {
            AccountExists = true,
            AccountVerified = true, // Or more logic
            Status = "Ok"
        };
    }
}

In order to set up with your newly designed converter:

cfg.CreateMap<AccountLogin, LoginUserResponseModel>().ConvertUsing(new AccountLoginConverter());

or

 cfg.CreateMap<AccountLogin, LoginUserResponseModel>().ConvertUsing<AccountLoginConverter>();

You could try ConvertUsing with a custom ITypeConverter:

public class MyConverter : ITypeConverter<AccountLogin, LoginUserResponseModel >
{
    public int Convert(AccountLogin source, LoginUserResponseModel destination, ResolutionContext context)
    {
        return new LoginUserResponseModel{
           AccountExists = source == null ? false : true,
           AccountVerified = false,
           Status = source == null ? "Error" : "Ok",
           "Token": null
        };
    }
}

Then map it with:

CreateMap<AccountLogin, LoginUserResponseModel>().ConvertUsing(new MyConverter());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM