私は答えがオーバーポストの問題を指していると思います。ビューで直接エンティティクラスを利用し、特にそのエンティティをデータベースに直接保存すると、悪意のあるユーザーがフォームを修正して、変更できないフィールドを投稿する可能性があります。
たとえば、ユーザーがウィジェットを編集できるフォームがあるとします。また、行レベルのアクセス権を持っているとしましょう。そのため、ユーザーは自分に属するウィジェットだけを編集できます。だから、私たち架空の悪意のあるユーザーであるJoeは、123というIDで編集できるウィジェットを編集します。しかし、彼はJaneのウィジェットを使いこなすことを決めたので、Id
というフォームにフィールドを追加し、Janeのウィジェットid。 Joeがウィジェットフォームを投稿すると、代わりにJaneのウィジェットが更新されます。
ビューモデルはこの問題を解決するためのものではありませんが、本来、ビューモデルをデータベースに直接保存することはできないため、この問題は基本的に無効になります。エンティティをデータベースに保存する前に、ビュー・モデルの値をエンティティにマップする必要があります。その結果、マッピングされたものとマッピングされないものを明示的に制御するので、上記の例でJoeを変更すると、エンティティにマッピングされていないため、IDが変更されなくなります。
実際には、実際のの問題は、直接ユーザーが投稿したものをそのままデータベースに保存することです。実際には、エンティティクラスをビューに「モデル」としてフィードすることはできますが、ポストされたインスタンスは保存しないでください。代わりに、エンティティの新しいインスタンスを作成するか、データベースのインスタンスを新しいインスタンスから取得し、単純にそのインスタンスの値をそのインスタンスにマップします。再度、Id
のようなプロパティをマップしないので、再びJoeが挫折します。言い換えれば、問題を解決するのはビューモデルではなく、問題を解決するPOSTを介して作成されたものを直接保存するのに十分なユーザーを信頼することは決してありません。
マイクロソフトではBind
属性の形式で別のソリューションを提供しています。これにより、モデルバインディングプロセスのエンティティクラスに特定のプロパティを含める/除外することができます。たとえば、アクションのパラメータを[Bind(Exclude = "Id")]
に飾ることで、上記の問題を解決できる可能性があります。Id
の投稿された値は破棄されます。しかしはnumber of reasonsで恐ろしく、実際には使用しないでください。代わりに常にビューモデルを使用するか、モデルバインダによって作成されたエンティティインスタンスを直接保存しないでください。
ビューモデルを使用すると、アクティブなデータベースにまだ接続されているモデルを使用すると、DBにプッシュする前にデータを検証することができます。ビューは、場合によっては、真のビューモデルで可能です。 –
@Derek ViewModelを使用していない場合よりも不適切に接続を管理することに問題はありませんか? – Sinjai
問題は、モデルバインダーがモデル内の値を盲目的に更新することです。モデルがエンティティフレームワーク内のエンティティのようなものに接続されている場合、必要のないフィールドを更新する可能性があります。適切なビューモデルは、そのようなものから完全に切り離されます。 –