Search code examples
c#.netasp.net-coreautomapper

Use custom mapping in reverse map


This is my code:

public class PostDto : BaseDto<PostDto, Post>
{
    [JsonIgnore]
    public override int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string Title { get; set; }

    [Required]
    [DataType(DataType.Html)]
    public string Text { get; set; }

    [Required]
    [StringLength(500)]
    [DataType(DataType.Text)]
    public string ShortDescription { get; set; }

    [Required]
    public int TimeToRead { get; set; }

    [Required]
    [DataType(DataType.ImageUrl)]
    public string Image { get; set; }

    [Required]
    public int CategoryId { get; set; }

    [JsonIgnore]
    public DateTimeOffset Time { get; set; }

    [JsonIgnore]
    public int UserId { get; set; }

    public override void CustomMappings(IMappingExpression<Post, PostDto> mappingExpression)
    {
            mappingExpression.ForMember(
               dest => dest.Time,
               config => config.MapFrom(src => DateTimeOffset.Now));

            mappingExpression.ReverseMap().ForMember(
                dest => dest.Time,
                config => config.MapFrom(src => DateTimeOffset.Now));

            mappingExpression
                .ForMember(d => d.Time, opt => opt.MapFrom(src => DateTimeOffset.Now))
                .ReverseMap()
                .ForMember(d => d.Time, opt => opt.MapFrom(src => DateTimeOffset.Now))
                .ForPath(s => s.Time, opt => opt.MapFrom(src => DateTimeOffset.Now));
     }
}

And I get dto from controller, and map it to entity. I want to add Time when mapping Automatically but it's not work.
If I map from entity (post) to dto (postDto) for example to convert date to string, it's work but in reverse it's not work

My Controller:

public override Task<ApiResult<PostSelectDto>> Create(PostDto dto, CancellationToken cancellationToken)

Code to convert dto to entity(after map time in [model] is null or default value of datetimeoffset)

var model = dto.ToEntity(Mapper);

ToEntity method:

public TEntity ToEntity(IMapper mapper)
{
    return mapper.Map<TEntity>(CastToDerivedClass(mapper, this));
}

Solution

  • Based on this url we can add datetime like code that I send with override
    link

    Reason is because, UseValue is a static, so it’s set once when the MapProfile is instantiated and all subsequent .Map() invokes will use the same static value

    So I write custom map without use reflection to create map for entities and dto

    public class PostCustomMapping : IHaveCustomMapping
    {
        public void CreateMappings(Profile profile)
        {
            profile.CreateMap<Post, PostDto>().ReverseMap()
                .ForMember(dest => dest.Time,
                    opt =>
                        opt.MapFrom(src => DateTimeOffset.Now))
    
                .ForMember(dest => dest.Text,
                    opt =>
                        opt.MapFrom(src => src.Text.FixPersianChars()))
    
                .ForMember(dest => dest.Title,
                    opt =>
                        opt.MapFrom(src => src.Title.FixPersianChars()))
    
                .ForMember(dest => dest.ShortDescription,
                    opt =>
                        opt.MapFrom(src => src.ShortDescription.FixPersianChars()));
        }
    }