2014-02-21 2 views
3

У меня возникли проблемы с пониманием того, как работают asp.net mvc.asp.net mvc modelbinding не обязательные коллекции

Модели

public class Detail 
{ 
    public Guid Id { get; set; } 
    public string Title {get; set; }  
} 

public class Master 
{ 
    public Guid Id { get; set;} 
    public string Title { get; set; } 
    public List<Detail> Details { get; set; } 
} 

Посмотреть

<!-- part of master view in ~/Views/Master/EditMaster.cshtml --> 
@model Master 

@using (Html.BeginForm()) 
{ 
    @Html.HiddenFor(m => m.Id) 
    @Html.TextBoxFor(m => m.Title) 

    @Html.EditorFor(m => m.Details) 

    <!-- snip --> 
} 

<!-- detail view in ~/Views/Master/EditorTemplates/Detail.cshtml --> 
@model Detail 

@Html.HiddenFor(m => m.Id) 
@Html.EditorFor(m => m.Title) 

Контроллер

// Alternative 1 - the one that does not work 
public ActionResult Save(Master master) 
{ 
    // master.Details not populated! 
} 

// Alternative 2 - one that do work 
public ActionResult Save(Master master, [Bind(Prefix="Details")]IEnumerable<Detail> details) 
{ 
    // master.Details still not populated, but details parameter is. 
} 

Вынесено HTML

<form action="..." method="post"> 
    <input type="hidden" name="Id" value="...."> 
    <input type="text" name="Title" value="master title"> 
    <input type="hidden" name="Details[0].Id" value="...."> 
    <input type="text" name="Details[0].Title value="detail title"> 
    <input type="hidden" name="Details[1].Id" value="...."> 
    <input type="text" name="Details[1].Title value="detail title"> 
    <input type="hidden" name="Details[2].Id" value="...."> 
    <input type="text" name="Details[2].Title value="detail title"> 
    <input type="submit"> 
</form> 

Почему хотите модель Связующее по умолчанию заполнения Подробности-свойство на модели? Почему я должен включать его в отдельный параметр в контроллер?

Я прочитал несколько сообщений об asp и привязке к спискам, включая Haackeds, которые упоминаются несколько раз в других вопросах. Это было this thread на SO, которые привели меня к опции [Binding(Prefix...)]. В нем говорится, что «модель, вероятно, слишком сложна», но что именно «слишком сложно» для стандартного связующего устройства?

+0

Вы посмотрели на возможность создания собственных связующих устройств? Вот хорошая рекомендация для пользовательских привязок моделей: [Из журнала MSDN] (http://msdn.microsoft.com/en-us/magazine/hh781022.aspx) – jacqijvv

+0

нет, я видел возможность, но я больше любопытно, почему asp не может решить этот случай сам ... – Vegar

+0

вы должны взглянуть на этот старый [пост] (http://haacked.com/archive/2008/10/23/model-binding-to -a-list.aspx /) Фила Хаака, он довольно четко объясняет, что заставляет тип слишком сложно связывать.Но в целом динамически невозможно (MVC DefaultModelBinder) определить, что «случайная» коллекция ** id ** и ** title ** в объекте Request на самом деле является частью коллекции без использования индексов. – jacqijvv

ответ

0

Модель в вашем вопросе не «слишком сложна». Однако список сложного типа (например, вашего объекта Details) будет сложным связыванием.

Для сложной привязки используются EditorTemplates. Этот editorTemplate указывает, как должен отображаться редактор для сложного типа. EditorTemplates находятся в папке EditorTemplates в папке, в которой находится вид. По умолчанию для editortemplate должно быть имя вашего класса сложного типа. Так вы случае вы должны назвать его Detail.cshtml

внутри editortemplate вы могли бы использовать что-то вроде:

@model Detail 

@Html.HiddenFor(m => m.Id) 
@Html.TextBoxFor(m => m.Title) 

Теперь, когда вы называете @Html.EditorFor(m => m.Details) в вашей regualar модели для каждого элемента в списке деталей, указанный отредактированный editortemplated будет отображаться.

В вас контроллер, где точки действия к, вы можете просто попросить экземпляр вам модели, как:

public ActionResult Save(Master model) 
{ 

} 

Теперь внутри метода Save, model.Details будут заполнены данными из вашей точки зрения.

Обратите внимание, что MVC будет возвращать данные только вашему контроллеру, который доступен в вашей форме. Все ваши данные, которые не отображаются, или нет в форме, не будут возвращены.

+0

Это именно то, что я сделал. Я вижу, что это не совсем понятно. Я немного отредактирую вопрос ... – Vegar

+0

Это было бы странно, потому что это должно сработать. Тогда мы, должно быть, что-то пропустили. Является ли этот редактор для (m => m.Details) представленным в вашей форме? – middelpat

+0

Да, все визуализируется, и все отправляется обратно на сервер. Разница в том, что в альтернативе 1 детали детали не преобразуются из данных формы в детализированные объекты, а в альтернативе 2 они есть. – Vegar

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