自动映射异常,尽管AssertConfigurationIsValid()成功



我真的很挠头。我已经从Automapper 2.2.1更新到3.1.1,代码在崩溃之前还能正常工作。我正在尝试获得更多的诊断信息来调试实际问题。

在单元测试中,我通过了,因为没有错误出现

[TestClass]
public class TestOldWcfEndpoint
{
    public TestContext TestContext { get; set; }
    bool FieldWasSpecified;
    [TestInitialize]
    public void TestInitialize()
    {
        AutoMapperUnity.RegistrationInUnitTesting();
        this.FieldWasSpecified = true;
    }
    [TestMethod]
    public void Test_OldWcfHosting_AutomapperConfigurationIsValid()
    {
        try
        {
            AutoMapper.Mapper.AssertConfigurationIsValid();
        }
        catch (AutoMapper.AutoMapperMappingException aex)
        {
            this.TestContext.WriteLine(aex.Message);
            throw;
        }
    }
}

AutoMapperUnity是一个静态帮助类,用于连接到Unity容器:

public static class AutoMapperUnity
{
    private static void Regsitrations()
    {
        Mapper.Reset();
        var business = new BusinessLogicMaps(); business.Configure();
        var api = new ApiServiceMaps(); api.Configure();
        var wcf = new OldWcfMaps(); wcf.Configure();
        Mapper.Configuration.AllowNullCollections = true;
    }
    public static void Registration(IUnityContainer container)
    {
        Regsitrations();
        container.RegisterType<IMappingEngine>(new InjectionFactory(_ => Mapper.Engine));
        container.RegisterType<IConfiguration>(new InjectionFactory(_ => Mapper.Configuration));
        container.RegisterType<IConfigurationProvider>(new InjectionFactory(_ => Mapper.Configuration));
    }
}

wcf地图出现了问题。Wcf端点构建在Web Api客户机使用的相同DTO契约之上。除了数据注释之外,Wcf契约是完全相同的。

public class OldWcfMaps
{
    void CreateMapForCodes()
    {
        Mapper.CreateMap<CodeTypeDTO, CodeTypeWcfDTO>()
            .ForMember(s => s.IDSpecified, o => o.Ignore());
        Mapper.CreateMap<CodeTypeWcfDTO, CodeTypeDTO>();
        Mapper.CreateMap<CodeDTO, CodeWcfDTO>()
            .ForMember(s => s.ActiveSpecified, o => o.Ignore())
            .ForMember(s => s.CodeTypeIDSpecified, o => o.Ignore())
            .ForMember(s => s.IDSpecified, o => o.Ignore());
        Mapper.CreateMap<CodeWcfDTO, CodeDTO>();
    }
    void CreateMapForCodeReports()
    {
        Mapper.CreateMap<CodeReportDTO, CodeReportWcfDTO>()
            .ForMember(s => s.ActiveSpecified, o => o.Ignore())
            .ForMember(s => s.AppIDSpecified, o => o.Ignore())
            .ForMember(s => s.IDSpecified, o => o.Ignore())
            .ForMember(s => s.CodeIDSpecified, o => o.Ignore())
        Mapper.CreateMap<CodeReportWcfDTO, CodeReportDTO>();
    }
    void CreateMapForShiftReports()
    {
        this.CreateMapForCodeReports();
        Mapper.CreateMap<ShiftReportDTO, ShiftReportWcfDTO>()
            .ForMember(s => s.NumberOfReportsSpecified, o => o.Ignore());
        Mapper.CreateMap<ShiftReportWcfDTO, ShiftReportDTO>();
    }
    public void Configure()        
    {
        this.CreateMapForCodes();
        this.CreateMapForShiftReports();
    }
}

}

[ServiceBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class TimeClockServices : ITimeClockServices
{
    /// <summary>
    /// Reference to the AutoMapper Engine.
    /// </summary>
    private readonly IMappingEngine MapperEngine;
    private readonly ILogFactory LogFactory;
    private readonly ITimeClockDataService TimeClockApi;
    public TimeClockServices(IMappingEngine mapper, ITimeClockDataService timeClockServices, ILogFactory logger)
    {
        this.MapperEngine = mapper;
        this.TimeClockApi = timeClockServices;
        this.LogFactory = logger;
    }
    public IEnumerable<CodeReportWcfDTO> GetCodeReports(ApplicationsEnum AppID, short DepartmentID, long CaseID, bool Active)
    {
        IEnumerable<CodeReportWcfDTO> groupOfWcfCodeReportDTOs = null;
        try
        {
            // Get Data using shared internal interface.
            IEnumerable<CodeReportDTO> codeReportDTOs =
                this.TimeClockApi.GetCodeReports(AppID, DepartmentID, CaseID, Active);
            // Convert the Data to the Wcf Extension Class.
            // **OFFENDING LINE**
            codeReportWcfDTOs =
                this.MapperEngine.Map<IEnumerable<CodeReportDTO>, IEnumerable<CodeReportWcfDTO>>(codeReportDTOs);
        }
        catch (BLException bex)
        {
            throw new FaultException<BLExceptionFault>(
                new BLExceptionFault("Business Engine Exception was thrown.", bex));
        }
        return codeReportWcfDTOs;
    }
}
这最终会导致错误:
Missing type map configuration or unsupported mapping.
Mapping types:
CodeReportDTO -> CodeReportWcfDTO
Api.Contract.Entities.CodeReportDTO -> Legacy.Contracts.WcfDTO.CodeReportWcfDTO
Destination path:
IEnumerable`1[0]
Source value:
Api.Contract.Entities.CodeReportDTO

只是上面我不知道它实际上是失败的,以更好地排除故障。DTO层也被映射到业务对象的等价物。

我错过了一些非常重要的东西。当我解决了Wcf特定的dto时,它是从代理客户端而不是服务器主机项目的单元测试项目中获取它们的。

这个错误是正确的,因为代理。= OldWcf.CodeTypeWcfDTO.

如果你遇到了这个问题,一定要检查你的命名空间,确保你在看正确的契约!

相关内容

  • 没有找到相关文章

最新更新