17

UpdateModelASP.NET MVCのメソッドの観点から、皆さんが「正しい動作」と見なされるべきだと感じていることを知りたいと思います。

私がここで尋ねる理由は、おそらくこの機能が「設計による」ものであるかどうか、誰かがそれがそのようになっている理由を明確にすることができ、おそらくそれを別の方法で呼び出して目的の機能を実現する方法であると思います。人々の%はこれが機能することを望みますか?

本質的に、私の不満は、内のバインディングプロセスの動作にありますUpdateModel

フォームのデータフィールドがデータベース内のモデルを反映する単純なアクションメソッドを介してフォームを更新する場合Save、最初にリクエストを保存するために、DBから既存のモデルを取得してから、関連するフィールドを更新します。これらは変更され、経由で送信され、既存のモデルにFormCollection更新されました。UpdateModelこの機能は機能しますが、このDBが入力されたオブジェクトの既存のプロパティのいずれかが「リセット」されているようです。つまり、明らかに新しいオブジェクトと一致するものを除いて、それがまったく新しいオブジェクトであるかのように、nullまたは初期化のデフォルトに設定されているということFormCollectionです。

これは問題です。これは、オブジェクトに存在するが、必ずしもフォームに存在するとは限らない既存のプロパティ(子コレクションやオブジェクト、日付、UIに面していないフィールドなど)が空であり、半分のデータが残っているためです。おそらくIDのスタックを含むすべての欠落データが0に設定されているため、DBに保存できない使用不可能なオブジェクト。

これは望ましくない動作であり、でUpdateModelプロパティが一致する場合にのみプロパティを更新する必要があると思いますFormCollection。これは、既存のすべてのプロパティは変更されないが、更新は設定されることを意味します。ただし、これまでに推測されたことから、明らかにそうではありません。オブジェクトの新しいコピーがフォームからプロパティを更新し、新しいオブジェクトを返すように見えます。

最後に、これがどれほどの負担であるかという観点から言えば、半複雑なフォームを保存し、既存のすべてのオブジェクトデータを保持するための唯一の方法は、プロパティを対応するフォームプロパティと手動で結合することです。フォームに存在するプロパティのみが更新されることを保証します。

私は推測する、

  1. これに同意する人は設計によるものですが、私の形のアプローチは最良の方法と結婚していますか?
  2. または、これでどのようにこれに取り組みましたか?

この人たちについて、お気軽にご意見をお聞かせください。ありがとうございます。

この問題に苦しんでいる人の別の例を次に
示します。複雑なデータ型のコレクションを使用してUpdateModelを呼び出すと、バインドされていないすべての値がリセットされますか?

4

4 に答える 4

15

UpdateModel() で発生している動作は、リスト バインディングのように聞こえます。その場合、UpdateModel() はリストの内容を吹き飛ばして再入力します。これに関する議論については、Hanselman のブログを参照してください。単一のオブジェクトを更新する場合、UpdateModel() はその個々のオブジェクトを更新し、対応するフォーム値を持たないプロパティをそのまま残します。

これらの問題の多くは、UpdateModel() がフォーム入力に基づいて (ドメイン モデルではなく) ビュー モデルを再作成することを実際に意図していることに要約されます。(ドメイン モデルは LINQ2SQL または EF モデル オブジェクトである可能性がありますが、ビュー モデルはコントローラーとビューの間の単なる契約であると言って、少し単純化しています。) すべての MVC チュートリアルとデモでは、UpdateModel() がデータベース オブジェクトに対して使用されますが、モデル バインドの意図された目的に関して誤解を招く可能性があるため、残念です。Robert の投稿は、UpdateModel() の実際の意図をよりよく示しています。

于 2009-08-07T04:07:34.097 に答える
5

UpdateModelの動作については正しいと思います。

ただし、ASP.NET MVCは「ラウンドトリップ」モデルに従います。つまり、すべてのフィールドの値をビューにプッシュしたか、またはユーザーからのすべてのフィールドを要求しています。

この往復の概念は非常に重要です。真のMVCモデルには、状態の概念がないことを忘れないでください。データベーステーブルからデータを取得し、このデータをビューにプッシュすると、データがユーザーに表示され、プログラムが停止します。ユーザーがデータを編集し、投稿ボタンをクリックすると、ビューがデータをコントローラーメソッドに投稿し、データがデータベースに保存され、プログラムが停止します。ある操作から次の操作への依存関係はまったくありません。

レコードとデータ構造の部分的な状態を保持しないというこの慣行により、(特にブラウザーの戻るボタンなどに関して)適切にスケーリングされ、適切に動作するアプリケーションを作成することが非常に簡単になります。

于 2009-08-07T03:47:39.017 に答える
2

リスト以外の型に対しては、UpdateModel を非常にうまく使用しています。includeProperties 配列の指定には常に注意を払っています (この問題が発生する可能性があるためではなく、セキュリティのためです。ユーザーがフォームをハックして (非常に簡単に) 日付を送信できるようにしたいですか?)。

これ以上改善できないと言っているわけではありません。

また、要件を設定する際に留意すべき実用的なポイント: POST を受信する Web サーバーにとって、空のフィールドは存在しないフィールドと同じです。つまり、UpdateModel が存在しないフォーム フィールド (日付など) を「リセット」しないように設計されている場合、同じ動作は、ユーザーが日付フィールドのテキストを削除して投稿した場合、更新されないことを意味します。空 (または null) を使用します。

ジェームズ

于 2009-08-07T10:48:55.657 に答える
2

しかし、オブジェクト モデル全体をフォームで表現するというアイデアにはまだ苦労しています。特に、2 つの子オブジェクトと 2 つのリストがあるとしたら、これがどのように簡単にマップされるかわかりません。オブジェクト マップ全体を表す隠しフィールドのスタック? ただ奇妙に思えます。

このためには、SubControllers や RenderAction などを調べる必要があります。あなたはそれらをグーグルすることができます。RenderAction をよく使います。これにより、別のデータを ViewData にプッシュすることなく、独自のコントローラー メソッドからウィジェットをページに挿入できます。

DBモデルに更新したいデータが完全にフォームに存在することを保証する必要はないと思います。これを容易にする db テーブルが 1 つもないと思います。たとえば、「作成日」や「更新日」を考えてみてください。これをフォームの非表示フィールドに格納するのは理想的ではないと思います。

あなたはそれについて正しいです。CreationDate、UpdatedBy などは、Controller (リポジトリを使用している場合は実際にはリポジトリ) で処理する必要があります。その時までに、ビュー モデルからデータベースを更新するために必要なすべてのフィールドが既にあるはずです。

「厳密に型指定されたビュー モデル」オブジェクトを使用する必要がある場合があります。よくわからない場合は、次のページを確認してください: http://nerddinnerbook.s3.amazonaws.com/Part6.htm

于 2009-08-07T22:58:57.163 に答える