带有 MVC 5 的 AutoMapper:缺少类型映射配置或不支持的映射

AutoMapper with MVC 5: Missing type map configuration or unsupported mapping

我无法让 AutoMapper 在我的 MVC5 设置中工作。 相同的代码在 UnitTest 中运行良好,但在 Web 上下文中却不行。 希望互联网的集体力量能在这里提供帮助。

我在 Global.asax

中创建我的地图
protected void Application_Start()
{
    ...
    AutoMapperWebConfiguration.Configure();
}

public static class AutoMapperWebConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.AddProfile(new WebProfile());
        });
    }
}

public class WebProfile : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<Repository.Model.Item, MVC5.Models.Vare>()
            .ForMember(i => i.Navn, opt => opt.MapFrom(c => c.Varenavn))
            .ForMember(i => i.Nummer, opt => opt.MapFrom(c => c.Varenummer))
            .ForMember(i => i.Leverandør, opt => opt.MapFrom(c => c.Leverandør))
            .ForMember(i => i.Indkøbsaktiv, opt => opt.MapFrom(c => c.Indkøbsaktiv))

            .Ignore(record => record.Salgspris)
            .Ignore(record => record.Lager);
    }
}

我正在使用来自

的忽略扩展

我尝试从我的存储库中获取项目,然后在返回我的视图之前映射它们。

List<Item> varer = repo.Search(søgning.VareNavn);
List<Vare> output = varer.Select(x => Mapper.Map<Repository.Model.Item, MVC5.Models.Vare>(x)).ToList();
søgning.Varer = output;
//Display Result
return View(søgning);

当我尝试使用此功能时,我在浏览器中收到此回复

Missing type map configuration or unsupported mapping.

Mapping types:
Item -> Vare
Repository.Model.Item -> MVC5.Models.Vare

Destination path:
Vare

Source value:
Repository.Model.Item

我相信我已经添加了正确的映射,但出于某种原因 AutoMapper 不同意。 当来自 UnitTest 的 运行 时,相同的代码有效。

[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
    MVC5.AutoMapperWebConfiguration.Configure();
}

[TestMethod]
public void Automapper_Item_to_Vare()
{
    // Assemble
    Mapper.AssertConfigurationIsValid();

    Repository.Model.Item item = new Repository.Model.Item()
    {
        Indkøbsaktiv = true,
        Leverandør = "Leverandør 1",
        Varenavn = "Lampe",
        Varenummer = "1234567890"
    };

    // Act
    MVC5.Models.Vare vare = Mapper.Map<MVC5.Models.Vare>(item);

    // Assert
    Assert.AreEqual(item.Indkøbsaktiv, vare.Indkøbsaktiv);
    Assert.AreEqual(item.Leverandør, vare.Leverandør);
    Assert.AreEqual(item.Varenavn, vare.Navn);
    Assert.AreEqual(item.Varenummer, vare.Nummer);
}

    [TestMethod]
    public void Automapper_ItemList_to_VareList()
    {
        // Assemble
        Mapper.AssertConfigurationIsValid();
        List<Repository.Model.Item> items = new List<Repository.Model.Item>()
        {
            new Repository.Model.Item()
            {
                Indkøbsaktiv = true,
                Leverandør = "Leverandør 1",
                Varenavn = "Lampe",
                Varenummer = "1234567890"
            },
            new Repository.Model.Item()
            {
                Indkøbsaktiv = true,
                Leverandør = "Leverandør 2",
                Varenavn = "Hammer",
                Varenummer = "9876543210"
            }
        };

        // Act
        List<MVC5.Models.Vare> varer = items.Select(x => Mapper.Map<MVC5.Models.Vare>(x)).ToList();

        // Assert
        Assert.AreEqual(2, varer.Count);
        Assert.AreEqual(items[0].Indkøbsaktiv, varer[0].Indkøbsaktiv);
        Assert.AreEqual(items[0].Leverandør, varer[0].Leverandør);
        Assert.AreEqual(items[0].Varenavn, varer[0].Navn);
        Assert.AreEqual(items[0].Varenummer, varer[0].Nummer);
    }

我之前在 automapper 上有过类似的经历,问题是我在应用程序的其他区域注册了映射,这覆盖了在 app_start 上创建的映射。

因此建议将您的映射注册集中在一个地方。 从技术上讲,您所描述的是由于缺少映射配置引起的,这可能是由于映射被覆盖或您的配置在应用程序启动时未被读取引起的。

我已经设法让我的代码进入工作状态。我无法完全解释我的情况,因为解决方案没有解释为什么我的测试用例有效。

我的初始化代码调用了两次 Mapper.Initialize() 这导致我需要的映射消失了。我的主要 Configure 方法和我的 RepositoryProfile class 都已初始化。

public static class AutoMapperWebConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.AddProfile(new WebProfile());
            cfg.AddProfile(new RepositoryProfile());
        });

        Mapper.AssertConfigurationIsValid();
    }
}

public class WebProfile : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<Repository.Model.Item, MVC5.Models.Vare>()
            .ForMember(i => i.Navn, opt => opt.MapFrom(c => c.Varenavn))
            .ForMember(i => i.Nummer, opt => opt.MapFrom(c => c.Varenummer))
            .ForMember(i => i.Leverandør, opt => opt.MapFrom(c => c.Leverandør))
            .ForMember(i => i.Indkøbsaktiv, opt => opt.MapFrom(c => c.Indkøbsaktiv))

            .Ignore(record => record.Salgspris)
            .Ignore(record => record.Lager)
            .Ignore(record => record.Antal);            
    }
}

public class RepositoryProfile : Profile
{
    protected override void Configure()
    {
        Mapper.Initialize(
            cfg => cfg.CreateMap<CacheInfo, Item>()
                .ForMember(i => i.Varenavn, opt => opt.MapFrom(c => c.VareNavn))
                .ForMember(i => i.Varenummer, opt => opt.MapFrom(c => c.VareNummer))
                .ForMember(i => i.Leverandør, opt => opt.MapFrom(c => c.Leverandør))
                .ForMember(i => i.Indkøbsaktiv, opt => opt.ResolveUsing<IndkobsaktivResolver>())
        );