在ASP.Net MVC视图模型嵌套模型的验证 [英] Validation of nested models in view model in ASP.Net MVC
问题描述
我有一个公司模型的应用程序。本公司模式有一个导航属性到一个地址模型(一个一对一的关系):
I have an application with a Company model. The Company model has a navigation property to an Address model (one-to-one relationship):
Company.cs
public class Company
{
public int CompanyID { get; set; }
public string Name { get; set; }
// Snip...
public virtual Address Address { get; set; }
}
我创建了一个视图模型来处理编辑,细节,并创建行动:
I've created a view model to handle the edit, detail, and create actions:
CompanyViewModel.cs
public class CompanyViewModel
{
public int CompanyID { get; set; }
[Required]
[StringLength(75, ErrorMessage = "Company Name cannot exceed 75 characters")]
public string Name { get; set; }
// Snip...
public Address Address { get; set; }
}
我在我的控制器映射来回模型和视图模型之间使用AutoMapper,一切工作正常。不过,我现在想的地址对象使用验证 - 我不想没有地址为present创建一家公司做
I'm using AutoMapper in my controller to map back and forth between the model and view model, and everything is working properly. However, I now want to use validation on the address object - I do not want a company to be created without an address being present.
我首先想到的是简约路线 - 我试图把一个[必需]注释的地址属性。这并没有做任何事情。
My first thought was the simple route - I tried putting a '[Required]' annotation on the Address property. This didn't do anything.
我当时以为这将是更好废除Address属性和抽象,在视图模型数据,所以我加了属性的视图模式都在我的地址类的属性:
I then thought it would be better to do away with the Address property and abstract that data in the view model, so I added properties to the view model for all the properties in my Address class:
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
// etc....
这似乎是很好的做法,但现在我的AutoMapper不能将这些属性的公司类的地址映射对象,所以我不得不在控制器手动映射:
This seemed like good practice, but now my AutoMapper can't map these properties to the Company class' Address object, so I had to manually map in the controller:
public ActionResult Details(int id = 0)
{
// Snip code retrieving company from DB
CompanyViewModel viewModel = new CompanyViewModel();
viewModel.Name = company.Name;
viewModel.Address1 = company.Address.Address1;
// Snip...
return View(viewModel);
}
这导致了很多额外的code在我的控制器,而不是一个很好的单行AutoMapper声明......有啥处理这个(在视图模型嵌套模型的验证)的正确方法?
This leads to a lot of extra code in my controller instead of a nice one-line AutoMapper statement...so what's the right way to deal with this (validation of nested models in a view model)?
它是很好的做法,Address属性直接在视图模型暴露,或更好的抽象出来,独立的属性,如我这样做?
Is it good practice to expose the Address property directly in the view model, or better to abstract it out with separate properties like I have done?
能否AutoMapper工作的情况下源和目标并不完全匹配?
Can AutoMapper work in a situation where source and destination are not exact matches?
推荐答案
如果你想automapper要能够在不显式指定映射模型,从你的属性映射到您的视图模型,你必须使用flattenting公约 :意味着你必须与它的属性名称拼接导航属性的名称。
if you want automapper to be able to map your properties from model to your viewmodel without specifying the mappings explicitly, you've got to use the "flattenting convention" : means that you must concatenate the navigation property's name with its property names.
所以,你的视图模型应该包含
So your ViewModel should contain
public int CompanyID { get; set; }
[Required]
[StringLength(75, ErrorMessage = "Company Name cannot exceed 75 characters")]
public string Name { get; set; }
// Snip...
//Address is the navigation property in Company, Address1 is the desired property from Address
public string AddressAddress1 { get; set; }
public string AddressAddress2 { get; set; }
public string AddressCity { get; set; }
public string AddressPostalCode { get; set; }
}
对了,你也可以告诉AutoMapper映射不明确尊重命名约定属性:
by the way, you can also tell AutoMapper to map properties which don't respect the naming convention explicitly :
Mapper.CreateMap<Company, CompanyViewModel>()
.ForMember(dest => dest.Address1, opt => opt.MapFrom(src => src.Address.Address1));
这篇关于在ASP.Net MVC视图模型嵌套模型的验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!