Mvc возвращает нулевое значение обратно из представления для объекта list <> в модели - PullRequest
2 голосов
/ 05 мая 2011

В проекте mvc 3 .Net FW 4.0 у меня есть данные, которые относятся к родительским дочерним отношениям, я построил свою модель так, чтобы она содержала список «потомков» с каждой родительской записью и отображала ее, как вследующий пример:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/ViewMasterPage.Master" Inherits="System.Web.Mvc.ViewPage<MvcTest.Models.ModelList>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    ShowPropReturn
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>ShowPropReturn</h2>

<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></script>

<% using (Html.BeginForm()) { %>
    <%: Html.ValidationSummary(true) %>
    <fieldset>
        <legend>ModelList</legend>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.MyProperty1) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.MyProperty1) %>
            <%: Html.ValidationMessageFor(model => model.MyProperty1) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.MyProperty2) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.MyProperty2) %>
            <%: Html.ValidationMessageFor(model => model.MyProperty2) %>
        </div>

        <table>
        <% foreach (var item in Model.MyProperty3)
           { %>
                <tr>
                    <td>
                        <%: Html.TextBoxFor(i => item.string1) %>
                    </td>
                    <td>
                        <%: Html.TextBoxFor(i => item.string2) %>
                    </td>
                </tr>

        <% } %>
        </table>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
<% } %>

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

</asp:Content>

Я понял, что если displayfor используется только для отображения значения поля, оно не публикуется, что имеет смысл.Но я получаю нулевое значение для объекта дочернего списка в модели на httppost, и мне нужно, чтобы эти элементы были отредактированы в том же представлении, оно также равно нулю в объекте formcollection, может кто-нибудь помочь мне в этом, пожалуйста?

Ответы [ 3 ]

3 голосов
/ 05 мая 2011

Вместо цикла foreach попробуйте использовать шаблон редактора:

<table>
    <%= Html.EditorFor(x => x.MyProperty3)
</table>

и внутри соответствующего шаблона редактора (~/Views/Shared/EditorTemplates/SomeModelType.ascx):

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<AppName.SomeModelType>" 
%>
<tr>
    <td>
        <%= Html.TextBoxFor(x => x.string1) %>
    </td>
    <td>
        <%= Html.TextBoxFor(x => x.string2) %>
    </td>
</tr>

Теперь это сгенерирует правильные имена полей ввода, чтобы при отправке значения формы были правильно связаны.

Примечание: в этом случае я предполагаю, что MyProperty3 в модели основного представления определяется следующим образом (набор SomeModelType):

public IEnumerable<SomeModelType> MyProperty3 { get; set; }
1 голос
/ 22 марта 2013

Ответ Дарина верен, но есть предостережение: вам нужно иметь поле в форме для каждого поля «набора» в модели, в противном случае оно не совпадает, и результирующий Список модели будет нулевым.

Рассмотрим этот случай для списка AccountModel:

public class AccountModel
{
    public AccountType Type { get; set; }
    public bool Selected { get; set; }
    public string Name { get { return Util.GetAccountTypeName(Type); } }
}

Родительское представление должно содержать только ...

    @Html.EditorFor(model => model.Accounts)

... где ...

    List<AccountModel> Accounts { get; set; }

... является частью вашей общей ViewModel.

Теперь, если вы создадите свой шаблон редактора, как этот ...

@model WebLinx.Models.AccountModel

    <div class="informationRow">        
        @Html.CheckBoxFor(x => x.Selected) 
        <div class="formLabel">
            @Html.Label(Model.Name)
        </div>
    </div>

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

Но если добавить одну дополнительную строку:

@model WebLinx.Models.AccountModel

    <div class="informationRow">        
        @Html.CheckBoxFor(x => x.Selected) 
        @Html.HiddenFor( x=> x.Type)  @* extra line with hidden field *@
        <div class="formLabel">
        @Html.Label(Model.Name)
        </div>
    </div>

тогда у вас будет полное совпадение между формой и объектом AccountModel, и список AccountModel будет содержать все элементы (и обновленные значения для флажков).

1 голос
/ 16 апреля 2012

Эрика - я смог сделать это с помощью цикла for

for (int i = 0; i < Model.MyList.Count(); i++) {
    @Html.TextboxFor(m => m.MyList[i].someproperty)
}

Однако мне больше нравится решение Дарина.

Также я обнаружил, что привязка не будет работать, если вы установите свойство Name помощника

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...