[英]How can I use Automapper to assign values to fields in destination model but not in source model?
I am getting the hang of Automapper in an ASP.NET MVC 5 application for the purpose of mapping a domain model to a ViewModel. 我正在将Automapper悬挂在ASP.NET MVC 5应用程序中,目的是将域模型映射到ViewModel。 There is a case that I still don't know how to resolve: when the ViewModel (destination) has a property not in the domain model (source).
在某些情况下,我仍然不知道如何解决:当ViewModel(目标)具有不在域模型(源)中的属性时。
The two additional properties in the ViewModel are IEnumerables that I need to populate in the Controller. ViewModel中的两个附加属性是我需要在Controller中填充的IEnumerables。
As I explain in the comments in the Controller block (shown below), the domain model is the source and will be fed into the View table. 正如我在Controller块中的注释(如下所示)中所解释的那样,域模型是源模型,并将被馈送到View表中。 The additional two IEnumerables in the ViewModel will fill the DropDownLists in the
HTML.BeginForm()
block. ViewModel中另外两个IEnumerables将填充
HTML.BeginForm()
块中的DropDownLists。
The examples I have seen using .CreateMap<>().ForMember()
deal with calculations or transformations of properties in the source model, and not this case, where I am defining something in the controller based on the Action parameters. 我使用
.CreateMap<>().ForMember()
看到的示例处理源模型中属性的计算或转换,而不是这种情况,我在其中基于Action参数在控制器中定义某些内容。
My question is how to map the remaining IEnumerables, as defined in the controller? 我的问题是如何映射控制器中定义的其余IEnumerables?
Mapping Config in App_Start App_Start中的映射配置
public static class MappingConfig
{
public static void RegisterMaps()
{
AutoMapper.Mapper.Initialize(config =>
{
config.CreateMap<StudentRoster, StudentRosterViewModel>();
});
}
}
Model and ViewModel: 模型和视图模型:
[Table("StudentRoster")]
public partial class StudentRoster
{
public int ID { get; set; }
[Required]
[StringLength(3)]
public string Campus { get; set; }
[Required]
[StringLength(4)]
public string FiscalYear { get; set; }
[Required]
[StringLength(50)]
public string StudentName { get; set; }
public int StudentID { get; set; }
}
// ViewModel
public partial class StudentRosterViewModel
{
// Automapper successfully mappped the first five fields
// to the parent class
public int ID { get; set; }
public string Campus { get; set; }
public string FiscalYear { get; set; }
public string StudentName { get; set; }
public int StudentID { get; set; }
// These two fields are not in the parent class
public IEnumerable<SelectListItem> CampusListSelect { get; set; }
public IEnumerable<SelectListItem> FiscalYearSelect { get; set; }
}
Index Action in Controller: 控制器中的索引操作:
// GET: StudentRosterViewModels
public ActionResult Index(string campus = "MRA", string fy="FY16")
{
IEnumerable<StudentRoster> query = db.StudentRosters.Where(m=>m.Campus==campus).ToList();
// This successfully maps the domain model to the viewmodel
// This IEnumerable will display in the "Table"
IEnumerable<StudentRosterViewModel> mappedQuery =
AutoMapper.Mapper.Map<IEnumerable<StudentRoster>, IEnumerable<StudentRosterViewModel>>(query);
// The two remaining IEnumerables need to be mapped to 'mappedQuery'
// CampusListSelect and FiscalYearSelect
// These two IEnumerables will populate the dropdownlists in Html.BeginForm()
IEnumerable<SelectListItem> CampusList = new SelectList(new List<string> { "CRA", "DRA", "MRA", "PRA" }, campus);
IEnumerable<SelectListItem> FiscalYearList = new SelectList(new List<string> { "FY12", "FY13", "FY14", "FY15", "FY16" }, fy);
return View(mappedQuery.ToList());
}
You can try to use DynamicMap
to populate your items without creating additional classes for mapping. 您可以尝试使用
DynamicMap
填充项目,而无需创建其他映射类。
In case if you're using the old version of AutoMapper
(4.1 or below) the you can try something the following: 如果您使用的是旧版本的
AutoMapper
(4.1或更低版本),则可以尝试以下操作:
// GET: StudentRosterViewModels
public ActionResult Index(string campus = "MRA", string fy="FY16")
{
IEnumerable<StudentRoster> query = db.StudentRosters.Where(m=>m.Campus==campus).ToList();
// This successfully maps the domain model to the viewmodel
// This IEnumerable will display in the "Table"
IEnumerable<StudentRosterViewModel> mappedQuery =
AutoMapper.Mapper.Map<IEnumerable<StudentRoster>, IEnumerable<StudentRosterViewModel>>(query);
// The two remaining IEnumerables need to be mapped to 'mappedQuery'
// CampusListSelect and FiscalYearSelect
// These two IEnumerables will populate the dropdownlists in Html.BeginForm()
IEnumerable<SelectListItem> CampusList = new SelectList(new List<string> { "CRA", "DRA", "MRA", "PRA" }, campus);
IEnumerable<SelectListItem> FiscalYearList = new SelectList(new List<string> { "FY12", "FY13", "FY14", "FY15", "FY16" }, fy);
var objForDynamicMapping = new
{
CampusListSelect = CampusList,
FiscalYearListSelect = FiscalYearList
};
foreach(var mappedItem in mappedQuery)
{
// will create the mapping configuration dynamically
AutoMapper.Mapper.DynamicMap(objForDynamicMapping, mappedItem);
}
return View(mappedQuery.ToList());
}
In case if you're using the AutoMapper 4.2 or high. 如果您使用的是AutoMapper 4.2或更高版本。
Then you just need to put this row: 然后,您只需要把这一行:
var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
in place where you create the mapper configuration and then just use method Map
like: 在创建映射器配置的地方,然后仅使用
Map
方法,例如:
mapper.Map(objForDynamicMapping, mappedItem);
instead of DynamicMap
. 而不是
DynamicMap
。
Hope it will help. 希望它会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.