0

我真的在这方面摸不着头脑。我已经从 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 层也被映射到业务对象等价物。

4

1 回答 1

0

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

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

如果您遇到此问题,请务必检查您的 namspaces,以确保您正在查看正确的合同!

于 2014-04-03T18:09:06.427 回答