Asp.net MVC Razor:传递复杂模型数据

时间:2017-01-11 14:13:45

标签: asp.net-mvc entity-framework razor

我有两个班级:

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是一个复杂的数据类型而不是一个原始的,或者不是? 那么传递这种复杂数据模型的最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

您根本不需要Bind属性。

只是在您的视图中,输入应该绑定输入的名称属性AddressAddress.IDAddress.Address1Address.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();
}