首页 > 解决方案 > MVC,映射器将 ViewModel 传递给 CreateView 的问题

问题描述

我需要一些帮助。我正在使用我是初学者的 ASP.NET MVC。

我正在编写一个带有数据库和 3 个表的应用程序(2 个表仅用于父子下拉列表,第三个用于保存下拉列表中的数据并填写其他表单)。

我正在使用带有 SQL 的实体框架将我的数据库连接到 ASP.NET MVC,并使用来自数据库的自动生成模型。

我手动制作了所有三个表及其字段的 ViewModel,我需要将所有数据传递给 1 个视图(创建视图)

这是我收到错误的家庭控制器的代码。

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CountryStateContactsViewModel csvm)
{
    if (!ModelState.IsValid)
    {
        return View(csvm);
    }

    // Error happens here
    Contact contactModel = Mapper.Map<CountryStateContactsViewModel, Contact>(csvm); 
    db.Contacts.Add(contactModel);
    db.SaveChanges();

    return RedirectToAction("Index");
}

这是我得到的错误:

非静态字段、方法或属性 'Mapper.Map<CountryStateContactsViewModel, Contact>(CountryStateContactsViewModel) 需要对象引用

标签: asp.net-mvcentity-frameworkasp.net-mvc-4automapper

解决方案


根据 OP 评论,没有 AutoMapper 配置,没有它 AutoMapper 无法解析映射。

定义一个接口来抽象映射方法:

public interface IMappingService
{
    TDest Map<TSrc, TDest>(TSrc source) where TDest : class;

    TDest Map<TSrc, TDest>(TSrc source, TDest dest) where TDest : class;
}

实现接口:

public class MappingService : IMappingService
{
    private MapperConfiguration mapperConfiguration;
    private IMapper mapper;

    public MappingService()
    {
        mapperConfiguration = new MapperConfiguration(cfg =>
        {
            // Define here your mapping profiles... 
            cfg.AddProfile<ViewModelToDomainMappingProfile>();
            cfg.AddProfile<DomainToViewModelMappingProfile>();
        });
        
        // You may not want to assert that your config is valid, and that's ok.
        mapperConfiguration.AssertConfigurationIsValid();
        mapper = mapperConfiguration.CreateMapper();
    }

    public TDest Map<TSrc, TDest>(TSrc source) where TDest : class
    {
        return mapper.Map<TSrc, TDest>(source);
    }

    public TDest Map<TSrc, TDest>(TSrc source, TDest dest) where TDest : class
    {
        return mapper.Map(source, dest);
    }
}

现在您必须定义您的配置文件(示例):

public class ViewModelToDomainProfile: Profile
{
    public ViewModelToDomainProfile()
    {
        CreateMap<CountryStateContactsViewModel, Contact>();
    }
}


public class DomainToViewModelProfile: Profile
{
    public DomainToViewModelProfile()
    {
        CreateMap<CountryStateContactsViewModel, Contact>();
    }
}

最后,在控制器中注入您的 IMappingService:

private readonly IMappingService _mappingService;

public HomeController(IMappingService mappingService) {
    _mappingService = mappingService;
}

并像这样使用它:

_mappingService.Map<CountryStateContactsViewModel, Contact>(viewModel);

我喜欢这个解决方案,因为它很好地封装了所有内容。

编辑:@Arsalan Valoojerdi 比我快。但是,这样你有两种不同的方法。

注意:不要忘记在 IoC 容器(例如 Ninject)上定义对 IMappingService 的依赖。


推荐阅读