0

ViewModel の編集ビューに少し問題があります。初めて編集ビューをサーバーに投稿するとき、データベース ID が追加された同じ ViewModel で編集ビューを再度返す必要があります。

これは、適切なコントローラーの Edit メソッドです。

[HttpPost]
public ActionResult Edit(InvoiceDetailsViewModel invoice) {
  using (var context = new HyperContext(WebSecurity.CurrentUserId)) {
    if (ModelState.IsValid) {
      if (invoice.ID == 0) {
        var dbItem = Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice);
        context.Invoices.Add(dbItem);
        context.SaveChanges();
        var newInvoice = Mapper.Map<InvoiceDetailsViewModel>(dbItem);
        FillViewBag(context, newInvoice);
        newInvoice.Description = "TEST";
        return PartialView(newInvoice);
      }
      else {
        context.Entry(Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice)).State = System.Data.EntityState.Modified;
        context.SaveChanges();
        return Content(Boolean.TrueString);
      }
    }
    FillViewBag(context, invoice);
    return PartialView(invoice);
  }
}

ここで関連する部分は、invoice.IDが 0 の場所です。請求書は ID を取得するために DB に保存され、編集ビューに返されます。そのビューでは、初心者向けに次の行を取得しました。

@model eu.ecmt.RecruitmentDatabase.ViewModels.InvoiceDetailsViewModel

@using (Html.BeginForm("Edit", "Invoice", FormMethod.Post, new { id = "invoices-edit-form" })) {
    @Html.ValidationSummary(true)

    <script type="text/javascript">
        $(document).ready(function () {
            //$("#tabs").tabs();
            InitProfileUI();
        });
    </script>
    if (Model.ID != 0) {
        <script type="text/javascript">
            $(document).ready(function () {
                LoadList('/InvoiceDetail/List/@Model.ID', '', 'invoice-details');
            });
        </script>
    }
    <fieldset>
        <legend>Edit contract</legend>

        @Html.HiddenFor(m => m.ID)
        @Html.HiddenFor(m => m.InvoiceNumber)
        @Html.HiddenFor(m => m.Created)
        @Html.HiddenFor(m => m.CreatedBy)
        @Html.HiddenFor(m => m.Modified)
        @Html.HiddenFor(m => m.ModifiedBy)

このビューを最初にレンダリングするとき、LoadList呼び出しを含むスクリプト要素は出力に含まれていません。フォームが投稿され、更新されたビューモデルでビューがレンダリングされると、その要素が出力されます。ただし、請求書の ID を含む隠しフィールドにはまだ 0 が表示されます。したがって、本質的に、ここで何が起こっているかというと、ViewData ディクショナリ内のモデル オブジェクトが正しいバージョンであり、式で使用されているオブジェクトのようです。別の古いバージョンであること。

誰かがこれを説明して、私を正しい方向に向けてくれますか?

4

1 に答える 1

1

この投稿によると、これは仕様による動作のようです。

要約: HTMLHelper は最初に POST の値を使用し、次に実際のモデルの値を使用します。コントローラー メソッドで ModelState からそれらを削除すると、うまくいきました。

[HttpPost]
public ActionResult Edit(InvoiceDetailsViewModel invoice) {
  using (var context = new HyperContext(WebSecurity.CurrentUserId)) {
    if (ModelState.IsValid) {
      if (invoice.ID == 0) {
        ModelState.Remove("ID");
        ModelState.Remove("Created");
        ModelState.Remove("CreatedBy");
        ModelState.Remove("Modified");
        ModelState.Remove("ModifiedBy");
        var dbItem = Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice);
        context.Invoices.Add(dbItem);
        context.SaveChanges();
        invoice = Mapper.Map<InvoiceDetailsViewModel>(dbItem);
        FillViewBag(context, invoice);
        return PartialView(invoice);
      }
      else {
        context.Entry(Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice)).State = System.Data.EntityState.Modified;
        context.SaveChanges();
        return Content(Boolean.TrueString);
      }
    }
    FillViewBag(context, invoice);
    return PartialView(invoice);
  }
}
于 2013-02-22T09:13:16.637 に答える