سؤال

I am really scratching my head on this. I had updated from Automapper 2.2.1 to 3.1.1 and code that was working before broke. I am trying to get more diagnostic information to debug the actual problem.

In the unit test I get a pass since no errors are present

[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;
        }
    }
}

The AutoMapperUnity is a static helper class to wire up to the Unity container:

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));
    }
}

The issue arises with the wcf maps. The Wcf end point builds on the same DTO contracts that is used by the Web Api clients. The Wcf Contracts are exactly the same except for the data annotations.

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;
    }
}

This eventually leads to the error:

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

With just the above I don't know what it is actually failing on to better troubleshoot. The DTO layer also gets mapped to the Business Object equivalents.

هل كانت مفيدة؟

المحلول

I had missed something very important. When I had resolved the the Wcf specific DTOs it was getting them from the Unit Test project which is the proxy client not the server host project.

This error is correct because Proxy.CodeTypeWcfDTO != OldWcf.CodeTypeWcfDTO.

If you have run into this issue make sure to check your namspaces that your looking at the right contracts!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top