Как получить список IEnumerable в модели, отображаемой для модели представления, обратно в контроллер после публикации

У меня есть текстовый файл, и когда пользователи загружают файл, метод действия контроллера анализирует этот файл с помощью конечного автомата и использует общий список для хранения некоторых значений. Я передаю это обратно в представление в виде IEnumerable. В моем основном представлении, основанном на этом перечисляемом списке, я отображаю частичное представление для повторения элементов и отображения меток и текстового поля. Пользователи могли добавлять свои данные в текстовую область. Когда пользователи нажимают кнопку сохранения, этот перечисляемый список из отображаемого частичного представления становится нулевым. поэтому, пожалуйста, посоветуйте любые решения.

вот мой основной вид

@model RunLog.Domain.Entities.RunLogEntry
@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";

}

   @using (Html.BeginForm("Create", "RunLogEntry", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {

<div id="inputTestExceptions" style="display: none;">
        <table class="grid" style="width: 450px; margin: 3px 3px 3px 3px;">
            <thead>
                <tr>
                    <th>
                        Exception String
                    </th>
                    <th>
                        Comment
                    </th>
                </tr>             </thead>

            <tbody>
                @if (Model.TestExceptions != null)
                {
                    foreach (var p in Model.TestExceptions)
                    {
                        Html.RenderPartial("RunLogTestExceptionSummary", p);

                    }
                }
            </tbody>
        </table>

    </div>
     }

частичное представление следующим образом:

@model RunLog.Domain.Entities.RunLogEntryTestExceptionDisplay
<tr>
    <td>
    @Model.TestException@
       </td>
        <td>@Html.TextAreaFor(Model.Comment, new { style = "width: 200px; height: 80px;" })
    </td>
</tr>

Действие контроллера

[HttpPost]
    public ActionResult Create(RunLogEntry runLogEntry, String ServiceRequest, string Hour, string Minute, string AMPM,
                                 string submit, IEnumerable<HttpPostedFileBase> file, String AssayPerformanceIssues1, IEnumerable<RunLogEntryTestExceptionDisplay> models)
    {

}

Проблема заключается в тестовых исключениях, которые содержат строку исключения, а комментарий возвращает значение null.

ОБНОВИТЬ

public class RunLogEntry
{
   SOME OTHER FIELDS

    [NotMapped]
    public IEnumerable<RunLogEntryTestExceptionDisplay> TestExceptions { get; set; }
}



public class RunLogEntryTestExceptionDisplay
{
    public string TestException { get; set; }
    public string Comment { get; set; }
}



@using (Html.BeginForm("Create", "RunLogEntry", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
         if (Model.TestExceptions != null)
           {
               if (Model.TestExceptions.Count() > 0)
               {
        <div class="bodyContent">
            <span class="leftContent">
                @Html.Label("Test Exceptions")
            </span><span class="rightContent"><span id="TestExceptionChildDialogLink" class="treeViewLink">
                Click here to View Test Exceptions</span>
                <br />
                <span id="TestExceptionDisplay"></span>
                @Html.HiddenFor(model => model.TestExceptions)
                @*<input id="ExceptionString" type="hidden" value="@Model.ExceptionString" />*@
            </span>
        </div>
               }
           }


   <div id="inputTestExceptions" style="display: none;">
        <table class="grid" style="width: 450px; margin: 3px 3px 3px 3px;">
            <thead>
                <tr>
                    <th>
                        Exception String
                    </th>
                    <th>
                        Comment
                    </th>
                </tr>
            </thead>
            @if (Model.TestExceptions != null)
            {
                var index = 0;
                foreach (var p in Model.TestExceptions)
                {
                <tr>
                    <td>@p.TestException
                        <input type="hidden" name="RunLogEntry.TestExceptions[@index].ExceptionString" value="@p.TestException" />
                    </td>
                    <td>
                        <textarea name="RunLogEntry.TestExceptions[@index].Comment" style ="width: 200px; height: 80px;">@p.Comment</textarea>
                        <input type="hidden" name="RunLogEntry.TestExceptions[@index].Comment" value="@p.Comment" />
                    </td>
                    @* Html.RenderPartial("RunLogTestExceptionSummary", p);*@
                </tr>
                                                                                                 index++;
                }

            }
        </table>
    </div>
}

person user1475788    schedule 20.09.2012    source источник


Ответы (1)


Чтобы опубликовать коллекцию, вам нужно назвать элементы формы в стиле массива. Вам также нужно будет сохранить счетчик, чтобы вы могли установить индекс массива в именах/идентификаторах элементов html.

@{var index = 0;}
@foreach (var p in Model.TestExceptions) {
  <tr>
    <td>
      @Model.TestException@
     </td>
      <td>
          <textarea name="@Html.FieldNameFor(m => m.TestExceptions[@index].Comment" id="@Html.FieldIdFor(m => m.TestExceptions[@index].Comment" style ="width: 200px; height: 80px;">@p.Comment</textarea>
          <input type="hidden" name="@Html.FieldNameFor(m=> m.TestExceptions[@index].ExceptionString" id="@Html.FieldIdFor(m=> m.TestExceptions[@index].ExceptionString" value="@p.ExceptionString" />
      </td>
  </tr>
index++;
}

Я не знаю, как выглядит ваша модель, но вы упомянули строку исключения, поэтому я использовал скрытый элемент формы для хранения значения свойства «ExceptionString», чтобы привязка модели могла получить эти значения при POST.

Если у вашего класса RunLogEntry есть другие свойства помимо коллекции TestExceptions, вы можете убедиться, что он будет корректно связываться с POST, включив элементы формы, которые будут отображаться в свойствах RunLogEntry. Например, если у вас есть свойство RunLogEntry.Foo, вы должны поместить его где-нибудь вне указанного выше цикла:

<input type="hidden" name="RunLogEntry.Foo" value="@Model.Foo" />
person Giscard Biamby    schedule 21.09.2012
comment
Это свойство модели RunLogEntry public IEnumerable‹RunLogEntryTestExceptionDisplay› TestExceptions { get; задавать; } - person user1475788; 21.09.2012
comment
тогда есть эта @model RunLog.Domain.Entities.RunLogEntryTestExceptionDisplay, которая имеет два свойства, т.е. тестовую строку исключения и строку комментария - person user1475788; 21.09.2012
comment
в основном представлении я отображаю тестовое исключение как частичное в цикле, оно отображается нормально, только в сообщении я не вижу значений - person user1475788; 21.09.2012
comment
Я избавился от частичного представления и отрендерил, как вы упомянули выше, testException по-прежнему возвращается как 0 для подсчета, и поэтому я не могу получить отдельные тестовые исключения и комментарии. - person user1475788; 21.09.2012
comment
Можете ли вы вставить код для класса RunLogEntry, а также для всех содержащихся в нем классов (включая RunLogEntryTestExceptionDisplay)? - person Giscard Biamby; 21.09.2012
comment
Эй, я только что обновил и опубликовал код для обоих этих классов, в сообщении в контроллере, если я смотрю в публикуемой модели записи журнала запуска, тестовые исключения: строка исключений должна быть правильным списком, потому что это то, что я только что отобразил в представлении, пользователи не будут изменять строку исключения и добавлять комментарии только в том случае, если они захотят добавить. - person user1475788; 22.09.2012
comment
В действии контроллера связаны ли какие-либо другие свойства RunLogEntry? - person Giscard Biamby; 22.09.2012
comment
О да, все остальные свойства отображаются в представлении и правильно отправляются обратно в контроллер. - person user1475788; 22.09.2012
comment
Другие ошибки: вы назначаете свойство .Comment дважды в html-форме: один раз в <textarea> и один раз в скрытом поле ввода. Скрытое поле предназначалось для свойства .TestException. Если вы не хотите привязывать это по какой-либо причине, не включайте скрытое поле. Я бы оставил скрытое поле и привязал его к .TestException, просто чтобы все было просто. Далее, почему у вас есть этот код: Html.HiddenFor(m=›m.TestExceptions)? - person Giscard Biamby; 22.09.2012
comment
Вы должны пытаться делать что-то одно за раз. Попробуйте просто отправить обратно IEnumerable‹RunLogEntryTestExceptionDisplay› сам по себе и привязать его к POST. Используйте сообщение в блоге Скотта Хансельмана о привязке к спискам/коллекциям, чтобы правильно понять эту часть. Получив это, вы легко сможете поместить IEnumerable‹› обратно в объект RunLogEntry и привязать его как RunLogEntry.TestExceptions. - person Giscard Biamby; 22.09.2012
comment
@if (Model.TestExceptions!= null) { var index = 0; foreach (var p в Model.TestExceptions) { ‹tr› ‹td›@p.TestException ‹input type=hidden name=RunLogEntry.TestExceptions[@index].ExceptionString [email protected] /› ‹/td› ‹/ тр›индекс++; } } - person user1475788; 22.09.2012
comment
я отображаю вышеприведенное в цикле, первый td я отображаю значение, а второй td — его скрытое значение для сообщения. - person user1475788; 22.09.2012
comment
У вас есть лишние поля формы. ‹textarea› и ‹input hidden› внутри вашего цикла имеют одинаковые значения атрибута name. Это, вероятно, сбивает с толку связыватель модели, когда вы пытаетесь выполнить POST. - person Giscard Biamby; 22.09.2012
comment
давайте продолжим это обсуждение в чате - person Giscard Biamby; 22.09.2012