Обновить сложную модель в ASP.NET MVC 2? - PullRequest
1 голос
/ 11 декабря 2010

Как мне обновить сложную модель?У меня есть следующее представление:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Tidrapportering.Models.Week>" %>
<% using (Html.BeginForm())
   {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
    <legend>Fields</legend>
    <table width="100%">
        <% foreach (var task in Model.Tasks)
           { %>
        <tr>
            <td>
                <%: task.Customer.CustomerName %>
            </td>
            <td>
                <%: task.TaskName %>
            </td>
            <td>
                <% foreach (var ts in task.TimeSegments)
                   { %>
                <%= Html.TextBox("Hours", ts.Hours)%>
                <% } %>
            </td>
        </tr>
        <% } %>
    </table>
    <p>
        <input type="submit" value="Spara tid" />
    </p>
</fieldset>
<% } %>
<div>
    <%: Html.ActionLink("Back to List", "Index") %>
</div>

И я попытался обновить его, как обычно, просто вызвав UpdataModel для объекта модели: UpdateModel (week);Но это не сработало.Поэтому я прочитал кое-что о необходимости обновлять каждое свойство отдельно в сложных моделях и попытался адаптировать его к моей ситуации.Вот моя попытка в контроллере:

    [HttpPost]
    public ActionResult EditTasks(int id, FormCollection collection)
    {
        //try
        //{
            Week week = _model.GetWeek(id);


            foreach (var task in week.Tasks)
            {
                foreach (var timeSegment in task.TimeSegments)
                {                        
                    UpdateModel(timeSegment.Hours, "Hours");
                }
            }


            //UpdateModel(week);
            _model.Save();
            return RedirectToAction("Index");
        //}
        //catch
        //{
        //    return View();
        //}
    }

Но это тоже не сработало.Кажется, это работает, если свойство является строкой, но это int, и компилятор жалуется, что это должен быть ссылочный тип для использования в качестве TModel.

Я не знаю, является ли этоКстати, мне просто нужно понять, как уметь обновлять модель сложного типа, подобную этой.Это не может быть слишком необычным, поэтому должен быть какой-то стандартный метод, но я не могу понять это ...

Любые идеи?

ОБНОВЛЕНИЕ:

Следующие работы:

Метод действия:

    [HttpPost]
    public ActionResult EditTasks(int id, FormCollection collection)
    {
        try
        {
            Week week = _model.GetWeek(id);
            for (int i = 0; i < week.TaskList.Count; i++)
            {
                var task = week.TaskList[i];
                for (int j = 0; j < task.TimeSegmentList.Count; j++)
                {
                    int hours = Int32.Parse(collection["TaskList[" + i + "].TimeSegmentList[" + j + "].Hours"]);
                    week.TaskList[i].TimeSegmentList[j].Hours = hours;
                }
            }

            //UpdateModel(week);
            _model.Save();
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

Вид:

    <% for (int i = 0; i < Model.TaskList.Count; i++)
       {
           var task = Model.TaskList[i];
    %>
    <tr>
        <td>
            <%: task.Customer.CustomerName %>
        </td>
        <td>
            <%: task.TaskName %>
        </td>
        <% for (int j = 0; j < task.TimeSegmentList.Count; j++)
           { %>
        <td>
            <%: Html.TextBoxFor(model => model.TaskList[i].TimeSegmentList[j].Hours, new { @class = "hourInput" })%>
        </td>
        <% } %>
    </tr>
    <% } %>

Однако обновление должно быть ручным, как это, котороекажется излишне сложным.Я нашел сообщение Фила Хаака (http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx)), в котором, кажется, предполагается, что это должно быть возможно сделать более простым способом, например так:

    [HttpPost]
    public ActionResult EditTasks(Week week)
    {
        try
        {
            UpdateModel(week);
            _model.Save();
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

Т.е. просто получение Недели в качестве параметра дляметод (в примере с Haacks даже не кажется, что он должен вызывать UpdateModel, просто достаточно привязать View к объектам, поэтому мне нужно было бы только сохранить его в базе данных ... Но это не такработа для меня. Возвращенный объект Week не похож на тот, что был отправлен в представление, в его наборах задач нет элементов, например,

Так почему же это не работает?

1 Ответ

1 голос
/ 11 декабря 2010

Попробуйте с for вместо foreach

<fieldset>
    <legend>Fields</legend>
    <table width="100%">
        <% for (int i = 0; i < Model.Tasks.Count; i++)
           { 
              var task = Model.Tasks[i];
        %>
        <tr>
            <td>
                <%: task.Customer.CustomerName %>
            </td>
            <td>
                <%: task.TaskName %>
            </td>
            <td>
                <% for (int j = 0; j < task.TimeSegments.Count; j++)
                   { %>
                <%= Html.TextBox("Model.Tasks["+i+"].TimeSegments["+j+"].Hours")%>
                <% } %>
            </td>
        </tr>
        <% } %>
    </table>
    <p>
        <input type="submit" value="Spara tid" />
    </p>
</fieldset>
...