2017-01-11 2 views
0

У меня есть два класса:Asp.net MVC 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; } 
} 

Так Спортивные ссылающийся Адрес Entity. Вид для создания Sportevent также содержит формы для адреса. Контроллер получает информацию, но что происходит с адресом? Как я могу передать их или он уже содержал

public ActionResult Create([Bind(Include = "EventsStart,EventsEnd, Address")] Sportevent sportevent){ 
... 
} 

Я думаю, что выше синтаксис привязки является неправильным, потому что адрес является сложным типом данных вместо этого primitve один, или нет? Итак, какова наилучшая практика для прохождения таких сложных данных?

ответ

1

Атрибут Bind может потребоваться в качестве меры предосторожности, если вы привязываетесь непосредственно к постоянным классам EF.

Чтобы избавиться от него, введите ViewModels, которые содержат только те поля, которые пользователь может изменить. Дополнительным преимуществом является то, что вы можете поместить View-centric свойства и методы в 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 
} 

В представлении, оказывают <input> как было упомянуто user7405157:

@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(); 
} 
+0

Итак, решение/трюк/идея ViewModels создает дополнительный слой, который представляет собой модель, в представлениях, правильно? ViewModel-Data нужно преобразовать explizit через код, правильно? Но у меня есть код – Kinimod

+0

Я думаю о том, чтобы получить класс и избавиться от свойств, но это разрушит концепцию разделения. – Kinimod

+0

Да, существует определенное количество реплик между ViewModel и EF Entity Model.Преобразование должно выполняться где-то в коде, даже если вы используете AutoMapper, вам нужно его настроить. Я не думаю, что работа с ViewModel из модели Entity будет работать, например, было бы невозможно скрыть идентификатор в CreateViewModel. –

2

Вам не нужно, чтобы атрибут Bind вообще отсутствовал.

Просто на ваш взгляд, для входов, которые должны связывать данные для Address в входного атрибута по имени поместить Address.ID, Address.Address1, Address.PostalCode и так далее. Обязательная привязка по умолчанию сделает вашу работу.

+0

Так что мой код выглядит следующим образом @ Html.EditorFor (модель => model.Address.Adress1, ...) и я прохожу модель, какой тип является Спортивные. Мне нравится использовать эту операцию привязки, как показано здесь [link] (https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud- application-framework-in-as-net-mvc-application) для предотвращения атак с подделкой запросов на межсайтовый запрос. – Kinimod

+0

Интересно. Я не думаю, что использование атрибута «Bind» в этом случае имеет какое-либо отношение к атакам подделки на основе межсайтового запроса. Для этого вы должны поместить '@ Html.AntiForgeryToken()' внутри вашей формы и украсить свое действие атрибутом 'ValidateAntiForgeryToken'. Что касается начального вопроса, то вы должны использовать все, что вам нужно (@ Html.EditorFor), если вы удаляете атрибут «Bind». – user7405157

+0

Хм. Я просто прочитал статью, которую вы предоставили, и теперь я знаю, что вы имеете в виду. вы всегда можете просто написать свое собственное связывание с моделью, я думаю. – user7405157

Смежные вопросы