簡體   English   中英

AutoMapper:使用 MemberList.Source 找到獲取未映射的成員

[英]AutoMapper: Getting Unmapped members were found with MemberList.Source

我們在我工作的地方做了很多映射。 我們使用並喜歡 AutoMapper。

我們想驗證我們的映射配置文件。 我們也經常想忽略一些遺留字段。 為此使用MemberList.Source會很棒。 而且它大部分都可以正常工作,除非我們希望對某些字段進行某種特殊處理。 如果我們想在字段甚至 ValueResolvers 上使用擴展方法,AutoMapper 在驗證期間會感到不安。它聲稱所說的字段沒有被映射。

這是設計使然,一個錯誤,我是“錯誤地持有它”還是只是遺漏了一些明顯的東西? 錯誤消息和重現如下。

兩個測試都出現此消息錯誤

AutoMapper.AutoMapperConfigurationException

# Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters

Source -> Destination (Source member list)
AutomapperRepro.Source -> AutomapperRepro.Destination (Source member list)

Unmapped properties:
FieldB

代碼:

using AutoMapper;
using Xunit;

namespace AutomapperRepro;

public class MappingTests
{
    [Fact]
    public void MappingProfile_IsValid()
    {
        var config = new MapperConfiguration(config => config.AddProfile<MappingProfile>());
        config.AssertConfigurationIsValid();
    }

    [Fact]
    public void MappingProfileValueResolver_IsValid()
    {
        var config = new MapperConfiguration(config => config.AddProfile<MappingProfileValueResolver>());
        config.AssertConfigurationIsValid();
    }
}

public class MappingProfile: Profile
{
    public MappingProfile()
    {
        CreateMap<Source, Destination>(MemberList.Source)
            .ForMember(dest => dest.FieldBPadded, opt => opt.MapFrom(s => s.FieldB.PadFieldB()));
    }
}

public class MappingProfileValueResolver : Profile
{
    public MappingProfileValueResolver()
    {
        CreateMap<Source, Destination>(MemberList.Source)
            .ForMember(dest => dest.FieldBPadded, opt => opt.MapFrom(new PaddingResolver(), src => src.FieldB));
    }
}

public static class PaddingExtentions
{
    public static string PadFieldB(this string src)
    {
        return src.PadLeft(10, '0');
    }
}

public class PaddingResolver : IMemberValueResolver<object, object, string, string>
{
    public string Resolve(object source, object destination, string sourceMember, string destinationMember,
        ResolutionContext context)
    {
        return sourceMember.PadFieldB();
    }
}

public record Source
{
    public string FieldA { get; set; } = string.Empty;
    public string FieldB { get; set; } = string.Empty;
}

public record Destination
{
    public string FieldA { get; set; } = string.Empty;
    public string FieldBPadded { get; set; } = string.Empty;
    public string SomeLegacyFieldThatCanBeIgnored { get; set; } = string.Empty;
    public string SomeLegacyFieldThatCanBeIgnored2 { get; set; } = string.Empty;
    public string SomeLegacyFieldThatCanBeIgnored3 { get; set; } = string.Empty;
}

@LucianBargaoanu 的兩個建議都是有效的👍 將 MapFrom 與變壓器相結合對我來說非常有用:

public class MappingProfileValueTransformer : Profile
{
    public MappingProfileValueTransformer()
    {
        CreateMap<Source, Destination>(MemberList.Source)
            .ForMember(dest => dest.FieldBPadded, opt =>
            {
                opt.MapFrom(s => s.FieldB);
                opt.AddTransform(dest => dest.PadFieldB());
            });
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM