1

テキスト ボックスと DropDownListFor がある編集ビューを設定しようとしています。DDLF にデータを入力する方法を見つけました。レンダリングされた値とポストされた値は正しいのですが、モデルを適切に更新できないようです。

更新しようとしているオブジェクトは LINQtoSQL から生成され、データベースには外部キー列があります。「Contains」関係になった LINQtoSQL クラス。DB の列を表す 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;
        }

また、このように ID フィールドを更新しようとすると、次のエラーが発生します。

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

エラー:新しい System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException() をスローします。

これは非常にお粗末な方法であると思われ、UpdateModel を機能させようとしています。

4

2 に答える 2

5

Joe Stevensのブログで、他の何かを探しているときに解決策を見つけました。

ViewModelを使用するときにControllerUpdateModelを使用する

キャッチは次のとおりです。ビューモデルを使用する場合、プロパティを正しくバインドするには、更新する実際のクラスを見つける方法を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>
于 2011-05-01T22:36:43.047 に答える
1

<select>ドロップダウン リストは、HTML フォームのタグで表されます。には、ID とテキストを含むタグの<select>リストが含まれます。<option>ユーザーがオプションを選択してフォームを送信すると、このオプションの対応する ID がサーバーに POST されます。しかもIDのみ。Editしたがって、 POST アクションで期待できるのは、選択したオプションの ID だけです。UpdateModel送信されたリクエスト パラメータを使用して、厳密に型指定されたオブジェクトに変換するだけです。しかし、POST されているのは単純な ID だけなので、取得できるのはそれだけです。そこから、対応するモデルを取得する場合は、この ID を使用してデータストアにクエリを実行する必要があります。したがって、存在しないものを取得することはできません。

于 2011-05-01T19:19:34.853 に答える