MVC,映射器将 ViewModel 传递给 CreateView 的问题
Posted
技术标签:
【中文标题】MVC,映射器将 ViewModel 传递给 CreateView 的问题【英文标题】:MVC, problem with Mapper passing ViewModel to CreateView 【发布时间】:2020-10-21 20:45:50 【问题描述】:我需要一些帮助。我正在使用我是初学者的 ASP.NET MVC。
我正在编写一个包含一个数据库和 3 个表的应用程序(2 个表仅用于父子下拉列表,第三个用于保存下拉列表中的数据并填写其他表单)。
我正在使用带有 SQL 的实体框架将我的数据库连接到 ASP.NET MVC,并使用来自数据库的自动生成模型。
我手动为所有三个表及其字段创建 ViewModel,我需要将所有数据传递给 1 个视图(创建视图)
这是我在 Home 控制器中遇到错误的代码。
[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)需要对象引用
【问题讨论】:
你能显示你的映射器配置文件吗? 是的,当然,但我不确定你的意思是什么:( 你在使用 Automapper? 是的,是的。我该如何解决这个问题? 您是否对 AutoMapper 进行过任何配置?如果有,请出示。 【参考方案1】:为了使用 AutoMapper,首先你应该在你的类之间创建映射。
public class ContactProfile
public AutoMapperProfile()
CreateMap<CountryStateContactsViewModel,Contact>();
public class AutoMapperConfiguration
public static void Initialize()
Mapper.Initialize(cfg = >
cfg.AddProfile(new ContactProfile());
);
最后在您的 Global.asax 中:
AutoMapperConfiguration.Initialize()
【讨论】:
我应该把这些类 ContactProfile 和 AutoMapperConfiguration 放在哪里 视情况而定。例如,您可以将其放在启动项目中的任何文件夹中。 所以我只是在启动时创建新文件夹,创建类并将两个类都放入其中? 是的。这是正确的。别忘了你应该在你的 Globa;.asax 文件中引入 AutoMapperConfiguration。 我收到错误 Mapper does not contain a definition for initialize at Mapper.Initialize【参考方案2】:根据 OP cmets 没有 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 的依赖。
【讨论】:
在此行执行时出错 cfg.AddProfile以上是关于MVC,映射器将 ViewModel 传递给 CreateView 的问题的主要内容,如果未能解决你的问题,请参考以下文章