我有两个班级:
public class Sportevent
{
public int ID { get; set; }
public DateTime EventsStart { get; set; }
public DateTime EventsEnd { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public int ID { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public int PostalCode { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Nation { get; set; }
}
所以Sportevent引用地址实体。 创建Sportevent的视图还包含地址的表单。 控制器接收信息,但地址会发生什么?我怎样才能传递它们或者它已经被包含
public ActionResult Create([Bind(Include = "EventsStart,EventsEnd, Address")] Sportevent sportevent){
...
}
我认为上面的绑定语法是不正确的,因为Address是一个复杂的数据类型而不是一个原始的,或者不是? 那么传递这种复杂数据模型的最佳做法是什么?
答案 0 :(得分:2)
您根本不需要Bind
属性。
只是在您的视图中,输入应该绑定输入的名称属性Address
,Address.ID
,Address.Address1
等Address.PostalCode
的数据。默认绑定将为您完成工作。
答案 1 :(得分:1)
如果您直接绑定到EF可持久类,则可能需要Bind
属性作为安全预防措施。
要摆脱它,请引入仅包含允许用户更改的字段的ViewModel。另一个好处是,您可以在ViewModel中放置以视图为中心的属性和方法,它们不会污染您的实体模型(关注点分离)。
public class CreateSporteventViewModel
{
// ID is not needed in create usecase because it will be assigned by EF
public DateTime EventsStart { get; set; }
public DateTime EventsEnd { get; set; }
public CreateAddressViewModel Address { get; set; }
}
public class CreateAddressViewModel
{
// ID is not needed in create usecase because it will be assigned by EF
// Example of View-centric attribute
[Display(ResourceType = typeof(Resources), Name = "Street")]
public string Address1 { get; set; }
// ... other properties relevant for create view
}
在视图中,按照user7405157提及的<input>
进行渲染:
@model CreateSporteventViewModel
@Html.EditorFor(m => m.EventsStart)
@Html.EditorFor(m => m.Address.Address1)
在控制器中,创建实体模型并填充它。存在有助于该映射步骤的库,例如, AutoMapper
public ActionResult Create(CreateSporteventViewModel viewModel){
var persistableEvent = new Sportevent {
EventsStart = viewModel.EventsStart,
// ...
};
var persistableAddress = new Address {
Address1 = viewModel.Address.Address1,
// ...
};
persistableEvent.Address = persistableAddress;
dbContext.Sportevents.Add(persistableEvent);
dbContext.SaveChanges();
}