UpdateModel не обновляет модель через ViewModel и свойство из DropDownListFor - PullRequest
1 голос
/ 01 мая 2011

Я пытаюсь настроить представление «Правка», в котором у меня есть текстовое поле и DropDownListFor.Я нашел способ заполнить DDLF, и отображаемые и отправленные значения верны, но я не могу заставить модель корректно обновляться.

Объект, который я пытаюсь обновить, генерируется из LINQtoSQL,и в базе данных он имеет столбец внешнего ключа.В классе LINQtoSQL, который привел к связи «Содержит».Я могу получить свойство ID, представляющее столбец в БД, а также объект, который он представляет.

        zupanija = new Zupanija();       //object that needs to be updated
        zupanija.Drzava;                 //object that i want to change to make the update
        zupanija.DrzavaID;               //Property linked to object that should change

Единственный способ выяснить, как выполнить обновление, - это получить значение из DDLF и использовать его.чтобы получить объект, который я хочу изменить следующим образом:

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
         var zupanija = repo.ZupanijaById(id);
         var drzava = new repoDrzava().DrzavaById(Convert.ToInt32(collection["Zupanija.DrzavaID"]));
         zupanija.Drzava = drzava;
        }

Также, когда я пытаюсь обновить поле идентификатора следующим образом, я получаю следующую ошибку:

           zupanija.DrzavaID = Convert.ToInt32(collection["Zupanija.DrzavaID"]);

Ошибка: бросить новый System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException ();

Мне кажется, это очень паршивый способ сделать это, и я пытаюсь заставить UpdateModel работать.

Ответы [ 2 ]

5 голосов
/ 02 мая 2011

Я нашел решение, когда искал что-то еще, в блоге Джо Стивенса:

Использование контроллера UpdateModel при использовании ViewModel

Проблема в следующем:Когда модель представления используется для правильной привязки свойств, необходимо «проинструктировать» помощника UpdateModel, как найти фактический класс, который мы хотим обновить.

Мое решение требуется для изменения

 UpdateModel(zupanija); to  UpdateModel(zupanija,"Zupanija");

Поскольку я использовал класс ViewModel, который содержал свойства пары вместе с основным классом данных, который я хотел обновить.Вот код, я надеюсь, это поможет понять:

    public class ZupanijaFVM
    {
    public IEnumerable<SelectListItem> Drzave { get; private set; }
    public Zupanija Zupanija { get; private set; }
    ...
    }

    // From Controller
    //
    // GET: /Admin/Zupanije/Edit/5
    public ActionResult Edit(int id)
    {
        var zupanija = repo.ZupanijaById(id);
        return zupanija == null ? View("Error") : View(new ZupanijaFVM(repo.ZupanijaById(id)));
    }

    //
    // POST: /Admin/Zupanije/Edit/5

    [HttpPost]
    public ActionResult Edit(int id, FormCollection collection)
    {
        var zupanija = repo.ZupanijaById(id);
        if (TryUpdateModel(zupanija, "Zupanija"))
        {
            repo.Save();
            return RedirectToAction("Details", new { id = zupanija.ZupanijaID });
        }
        return View(new ZupanijaFVM(zupanija));
    }

     //From View:
     @model VozniRed.Areas.Admin.Models.ZupanijeFVM

     <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>Zupanija</legend>
          @Html.HiddenFor(model => model.Zupanija.ZupanijaID)
         <div class="editor-label">
          @Html.LabelFor(model => model.Zupanija.Naziv)
         </div>
         <div class="editor-field">
          @Html.EditorFor(model => model.Zupanija.Naziv)
          @Html.ValidationMessageFor(model => model.Zupanija.Naziv)
         </div>
         <div class="editor-label">
          @Html.LabelFor(model => model.Zupanija.Drzava)
         </div>
         <div class="editor-field">
          @Html.DropDownListFor(model => model.Zupanija.DrzavaID, Model.Drzave)
          @Html.ValidationMessageFor(model => model.Zupanija.DrzavaID)
         </div>
         <p>
          <input type="submit" value="Save" />
         </p>
       </fieldset>
       }
    <div>
     @Html.ActionLink("Back to List", "Index")
    </div>
1 голос
/ 01 мая 2011

Раскрывающийся список представлен тегом <select> в форме HTML.<select> содержит список тегов <option>, каждый из которых содержит идентификатор и текст.Когда пользователь выбирает параметр и отправляет форму, соответствующий идентификатор этих параметров отправляется на сервер.И только удостоверение личности.Таким образом, все, что вы можете ожидать от действия Edit POST, это идентификатор выбранного параметра.И все, что UpdateModel делает, это использует параметры запроса, которые отправляются, и преобразует их в строго типизированный объект.Но поскольку все, что является POSTed - это простой идентификатор, это все, что вы можете получить.Оттуда вы должны запросить хранилище данных, используя этот идентификатор, если вы хотите получить соответствующую модель.Таким образом, вы не можете получить то, что не существует.

...