0

У меня есть модель представления, содержащая ссылку на класс и 2 коллекции IEnumerable.Коллекции MVC ViewModel имеют значение null при обратной передаче

public class BuildingTypeViewModel 
{ 
    public Static_Item BuildingType { get; set; } 
    public IEnumerable<Reading_Type> ReadingTypes { get; set; } 
    public IEnumerable<Building_Type_Reading> BuildingReadings { get; set; } 
} 

я заполнить этот ViewModel в Edit действия на контроллере

public ActionResult Edit(int id) 
    {    
     Static_Item staticItem = db.Static_Item.Find(id); 

     BuildingTypeViewModel model = new BuildingTypeViewModel 
     { 
      BuildingType = staticItem, 
      ReadingTypes=db.Reading_Type.ToList(), 
      BuildingReadings = db.Building_Type_Reading.Where(bt => bt.UN_Building_Type == staticItem.UN_Building_Type).ToList() 
     }; 

     return View(model); 
    } 

Тип здания на модели представления является классом с ID и описание и данные были бы что-то вроде этого:

UN_Building_Type=1, Description = "Hospital" 

IEnumerable из Reading_Type был бы так:

UN_Reading_Type = 1, Description = "Electric"  
UN_Reading_Type = 2, Description = "Gas" 

IEnumerable из Building_Type_Readings будет выглядеть так:

UN_Building_Type_Readings=1, UN_Building_Type=1, UN_Reading_Type = 1, Typical=300, Good=150 
UN_Building_Type_Readings=2, UN_Building_Type=1, UN_Reading_Type = 2, Typical=800, Good=400 

я загружаю эти данные в мой взгляд:

@model SSE.Enterprise.EE_Web_Portal.Models.BuildingTypeViewModel 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>Static_Item</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     @Html.HiddenFor(model => model.BuildingType.UN_Building_Type) 

     <div class="form-group"> 
      @Html.LabelFor(model => model.BuildingType.Description, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.BuildingType.Description, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.BuildingType.Description, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <label class="control-label col-md-2">Building Readings</label> 
      <div class="col-md-10"> 
       <table class="table"> 
        <tr> 
         <th/> 
         <th> 
          @Html.LabelFor(model=>model.BuildingReadings.FirstOrDefault().Typical) 
         </th> 
         <th> 
          @Html.LabelFor(model => model.BuildingReadings.FirstOrDefault().Good) 
         </th> 
        </tr> 

        @foreach (var item in Model.ReadingTypes) 
        { 
         <tr> 
          <td> 
           @Html.Label(item.Description) 
          </td> 
          <td> 
           @Html.EditorFor(model => model.BuildingReadings.FirstOrDefault(b => b.UN_Reading_Type == item.UN_Reading_Type).Typical, new { htmlAttributes = new { @class = "form-control" } }) 
          </td> 
          <td> 
           @Html.EditorFor(model => model.BuildingReadings.FirstOrDefault(b => b.UN_Reading_Type == item.UN_Reading_Type).Good, new { htmlAttributes = new { @class = "form-control" } }) 
          </td> 
         </tr> 
        } 
       </table> 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Save" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

Вот мой метод редактирования постбэк.

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit([Bind(Include = "BuildingType")] BuildingTypeViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Entry(model).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(model); 
    } 

Когда страница отправляется обратно на 2 IEnumerable коллекции являются недействительными, так что я не в состоянии сохранить данные, которые были введены.

Любая идея?

Ta

+0

Не должен ли ваш начальный текст иметь более подробную информацию? например: using (Html.BeginForm («Действие», «Контроллер», FormMethod.Post, ... –

+0

@MarkHomer: Нет. Все это необязательно. Если вы не передадите действие и контроллер, текущее действие и контроллер . По умолчанию используется POST, поэтому нет необходимости устанавливать это. –

+0

Вы не можете использовать цикл 'foreach' для создания элементов управления формулой - проверьте html свою генерацию. Атрибуты' name' вообще не имеют отношения к вашему mdoel. Вам нужно использовать цикл 'for' (и ваши свойства коллекции должны быть' IList 'not' IEnumerable '. Или, альтернативно, вам нужно использовать пользовательские' EditorTemplates' для typeof 'Reading_Type' и' Building_Type_Reading' –

ответ

2

Прежде всего, задав атрибут Bind(Include = "BuildingType") вы рассказываете MVC только связать это одно свойство. Удалите атрибут, и MVC попытается связать ваши коллекции 2 IEnumerable.

Затем проверьте свои звонки @Html.EditorFor. Я не уверен, что MVC может понять FirstOrDefault внутри. Попробуйте избежать выбора селекторов LINQ внутри вашего представления.

И после этого, поскольку @will упомянули, попробуйте изменить IEnumerable на List.

+0

Вы правы. Для правильной привязки вам нужно будет индексировать элементы в коллекции, т. Е. '@ Html.EditorFor (model => model.BuildingReadings [0].Типичный) ' –

+0

Я удалил атрибут Bind и LINQ, и он все тот же. – Sun

+0

Попробуйте и посмотрите на источник HTML на странице, которую вы получаете. Ваши входные данные должны выглядеть так: '', '' и т. Д. Если все остальное не удается, вы всегда можете следовать любому руководству по привязке к коллекциям в MVC (например [этот] (http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/)), затем постепенно модифицируйте его в соответствии с вашей моделью просмотра и посмотрите, на каком этапе происходит сбой привязки. – holdenmcgrohen

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