Как передать данные из View в контроллер в MVC 3 - PullRequest
1 голос
/ 14 февраля 2012

Я создал ViewModel с двумя вещами: контактом и списком телефонов для этого контакта.

Моя цель - добавить данные для нового контакта, добавить несколько телефонов, а затем сохранить с помощьюдействие контроллера.

Я отредактировал скаффолдинг Create.cshtml для своего контакта, добавил сетку для телефонов.Добавлен JavaScript для создания телефонов.Пока все хорошо.

Проблема в том, что когда я нажимаю кнопку «Создать» и возвращаюсь к контроллеру, у меня нет телефонов.Как (в представлении) добавить телефонные строки в мой IEnumerable?

РЕДАКТИРОВАТЬ: Извлек код из представления, который был неверным в этом контексте.

Моя ViewModel:

public class ContactViewModel
{
    public Contact Contact {get; set;}
    public IEnumerable<Phone> Phones { get; set; }    
}

Мой просмотр:

@model PilotKibsNet.Controllers.ContactViewModel      
<script type="text/javascript" src="../../Scripts/jquery-1.5.1.js"></script>

@{
    ViewBag.Title = "Create";
}

<h2>Create</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>

<script type="text/javascript">

    function Add() {
        $("#tbl > tbody:last").append("<tr><td>" + $("#Number").val() + "</td><td>" + $("#Kind").val() + "</td><td></td></tr>");

        $("#Number").val("");
        $("#Kind").val("");
    }

</script>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Contact</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Contact.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Contact.Name)
            @Html.ValidationMessageFor(model => model.Contact.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Contact.Address)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Contact.Address)
            @Html.ValidationMessageFor(model => model.Contact.Address)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Contact.City)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Contact.City)
            @Html.ValidationMessageFor(model => model.Contact.City)
        </div>


        <legend>Phone numbers</legend>
        <label>Number :</label>            
        @Html.TextBox("Number")
        <label>Kind :</label>
        @Html.TextBox("Kind")
        <input type="button" value="Add" onclick="Add()" />

        <table id="tbl">
            <tr>
                <th>
                    Phone
                </th>
                <th>
                    Kind
                </th>
                <th></th>
            </tr>

         <tbody>
        </tbody> 
        </table>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

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

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

    [HttpPost]
    public ActionResult Create(ContactViewModel contactViewModel)
    {
        if (ModelState.IsValid)
        {
            contactViewModel.Contact.id = Guid.NewGuid();

            db.Contacts.AddObject(contactViewModel.Contact);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(contactViewModel.Contact);
    }

Как вернуть телефоны на сервер?!?

1 Ответ

2 голосов
/ 14 февраля 2012

У вас есть только шаблоны отображения для этой коллекции телефонов. Никакие значения не будут отправлены на сервер. Вы можете использовать скрытые поля, если пользователь не должен редактировать значения или текстовые поля, если он есть.

Также я бы заменил цикл foreach на ваш взгляд на шаблон редактора:

if (Model != null)
{
    @Html.EditorFor(x => x.Phones)
}

и затем я определю шаблон редактора, который будет отображаться для каждого элемента коллекции телефонов (~/Views/Shared/EditorTemplates/Phone.cshtml):

@model Phone
<tr>
    <td>
        @Html.DisplayFor(x => x.Number)
        @Html.HiddenFor(x => x.Number)
    </td>
    <td>
        @Html.DisplayFor(x => x.Type)
        @Html.HiddenFor(x => x.Type)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id = Model.id }) |
        @Html.ActionLink("Details", "Details", new { id = Model.id }) |
        @Html.ActionLink("Delete", "Delete", new { id = Model.id })
    </td>
</tr>

Я использовал скрытые поля, чтобы сохранить значения модели, чтобы при отправке формы на сервер они были отправлены.

Другой, и IMHO, лучший подход, если пользователь не должен редактировать эти значения в таблице, - это просто повторно получить их в вашем действии POST из вашей базы данных.

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