XamDev
XamDev

Reputation: 3647

How to preserve values in destination using auto mapper in .net core

We are using AutoMapper (9.0.0) in .net core for mapping values between source and destination. Till time this is working fine. However, we need to keep some of the values in destination as it is after mapping.

We have tried to used UseDestinationValue() and Ignore() methods on member, but it is not preserving the existing values. Below is the code for the same.

RequestModel

public class RequestModel
{
    public int Id { get; set; }
    public int SubmittedById { get; set; }
    public string Description { get; set; }
    public string Location { get; set; }
}

RequestDto

public class RequestDto
{
    public int Id { get; set; }
    public int SubmittedById { get; set; }
    public string Description { get; set; }
    public string Location { get; set; }
    public string SubmittedByName { get; set; }
}

We are accepting Dto in API as request parameter API

[HttpPost]
        public IActionResult Save([FromBody] RequestDto requestDto)
        {
           // Some logic to save records
        }

So, before saving the records we are mapping RequestDto to RequestModel and passing that model to DAL layer to save the records like this

var requestModel = MapperManager.Mapper.Map<RequestDto, RequestModel>(RequestDto);

And call to data layer

var requestModel = DAL.Save(RequestModel)

So, after receiving the updated request model we are again mapping it to requestDto, in this case we are loosing the value for SubmittedByName property.

return MapperManager.Mapper.Map<RequestModel, RequestDto>(requestModel);

Mapper Class

public class RequestProfile: Profile
{
     public RequestProfile()
       {
           CreateMap<RequestModel, RequestDto>()
           CreateMap<RequestDto, RequestModel>()
       }
}

This SubmittedByName column is not present in the Request table, but we want to utilize its value after saving the records.

So, how can we preserve the destination value after mapping.

Any help on this appreciated !

Upvotes: 0

Views: 2206

Answers (2)

Pepelui360
Pepelui360

Reputation: 457

I think you have to use the Map overload that accepts destination.

This works for me, using same model / dto you posted, in a console application:

    var config = new MapperConfiguration(cfg => cfg.CreateMap<RequestModel, RequestDto>().ReverseMap());
    var mapper = config.CreateMapper();

    var source = new RequestDto
    {
        Id = 1,
        SubmittedById = 100,
        SubmittedByName = "User 100",
        Description = "Item 1",
        Location = "Location 1"
    };

    Console.WriteLine($"Name (original): {source.SubmittedByName}");
    var destination = mapper.Map<RequestDto, RequestModel>(source);
    Console.WriteLine($"Name (intermediate): {source.SubmittedByName}");
    source = mapper.Map<RequestModel, RequestDto>(destination, source);
    Console.WriteLine($"Name (final): {source.SubmittedByName}");

The standard Map method creates a new object but the overloaded method uses existing object as destination.

Upvotes: 2

Hoshani
Hoshani

Reputation: 846

We have tried to used UseDestinationValue() and Ignore() methods on member, but it is not preserving the existing values. Below is the code for the same.

since that didn't work for you

I would suggest creating a generic class like this (assuming you have multiple classes of RequestDto)

class RequesterInfo<T>
{
    public string RequesterName { get; set; } // props you want to preserve
    public T RequestDto { get; set; } // props to be mapped 
}

by keeping the mapping as it is, and modifying your code to something like this:

var requestModel = MapperManager.Mapper.Map<RequestDto, RequestModel>(RequesterInfo.RequestDto);

so what happens is that you modify the T RequestDto part of the object without modifying other properties.

Upvotes: 0

Related Questions