AutoMapper复杂视图模型属性
本文关键字:属性 模型 视图 复杂 AutoMapper | 更新日期: 2023-09-27 18:36:39
我希望你能帮我解决我在ASP测试中遇到的一个Automapper问题。NET MVC应用程序。
我环顾四周,找不到任何与我试图使用嵌套ViewModels实现的目标类似的东西。
基本上,我有这2个领域模型…
namespace Test.Domain.Entities
{
public class Contact
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public Name Name { get; set; }
public string Contact_Landline { get; set; }
public string Contact_Mobile { get; set; }
[DataType(DataType.EmailAddress)]
public string Contact_Email { get; set; }
}
}
而且。。
namespace Test.Domain.Entities
{
public class Name : DisplayableModel
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public string Name_Forename { get; set; }
public string Name_Surname { get; set; }
public string GetFullName()
{
return Name_Forename + ' ' + Name_Surname;
}
}
}
我有这两个ViewModel…
namespace Test.WebUI.Models
{
public class ContactViewModel :
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public NameViewModel Name { get; set; }
public string Contact_Landline { get; set; }
public string Contact_Mobile { get; set; }
[DataType(DataType.EmailAddress)]
public string Contact_Email { get; set; }
}
}
还有…
namespace Test.WebUI.Models
{
public class NameViewModel
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public string Name_Forename { get; set; }
public string Name_Surname { get; set; }
}
}
我想将ContactViewModel返回到我的视图,其中Name属性填充有填充Contact域对象的Name属性。
我的控制器里有这个代码…
Mapper.CreateMap<Name, NameViewModel>();
Mapper.CreateMap<Contact, ContactViewModel>();
var contact = Mapper.Map<Contact, ContactViewModel>(repository.Contact.Where(c => c.ID == id).Single());
return View(contact);
这就是我遇到问题的地方,我的Name属性从未被填充。
我之所以选择以这种方式设计我的应用程序,是因为我的视图由自定义模型模板组成,这样我就可以在不重复代码的情况下一致地呈现NameViewModel对象,就像这个简单的例子…
@model Test.WebUI.Models.NameViewModel
First
@Model.Name_Forename
Last
@Model.Name_Surname
如果有人能帮我解释我应该如何用AutoMapper填充ContactViewModel的NameViewModel对象,我将不胜感激。
谢谢。Jim
这应该是开箱即用的,如下所示:
public class Name
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public string Name_Forename { get; set; }
public string Name_Surname { get; set; }
public string GetFullName()
{
return Name_Forename + ' ' + Name_Surname;
}
}
public class Contact
{
public int ID { get; set; }
public Name Name { get; set; }
public string Contact_Landline { get; set; }
public string Contact_Mobile { get; set; }
public string Contact_Email { get; set; }
}
public class NameViewModel
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public string Name_Forename { get; set; }
public string Name_Surname { get; set; }
}
public class ContactViewModel
{
[HiddenInput(DisplayValue = false)]
[Key]
public int ID { get; set; }
public NameViewModel Name { get; set; }
public string Contact_Landline { get; set; }
public string Contact_Mobile { get; set; }
[DataType(DataType.EmailAddress)]
public string Contact_Email { get; set; }
}
class Program
{
static void Main()
{
Mapper.CreateMap<Name, NameViewModel>();
Mapper.CreateMap<Contact, ContactViewModel>();
var contact = new Contact
{
Name = new Name
{
Name_Forename = "forename"
}
};
var vm = Mapper.Map<Contact, ContactViewModel>(contact);
Console.WriteLine(vm.Name.Name_Forename);
}
}
按预期打印:
forename
因此,请确保repository.Contact.Where(c => c.ID == id).Single()
调用返回一个Contact
实例,该实例的Name
属性已正确实例化并包含其属性的值。
现在,也就是说,你的代码有几个问题:
- 您已经用
[HiddenInput]
属性修饰了域模型属性,该属性是视图特定的内容,属于您的视图模型 - 您已经使用
[Key]
属性装饰了视图模型属性。这是特定于数据访问的东西,视图模型应该是不可知的 - 您正在控制器操作中调用
Mapper.CreateMap<TSource, TDest>
方法。这是错误的。在应用程序域的整个生命周期中,映射定义应该只执行一次。这种情况通常发生在Application_Start
内部调用的辅助方法中,以确保映射定义只完成一次。在控制器操作中,您应该只使用Mapper.Map<TSource, TDest>
方法来执行实际映射
如前所述,您应该只定义一次映射(在APP_Start文件夹中(不确定这是否正是你所需要的,但你可以通过以下方式进行映射:
Mapper.CreateMap<Contact, ContactViewModel>()
.ForMember(c => c.Name, opt => opt.MapFrom(o => o.Name_Forename + " " + o.Name.Lastname);