4

MVC 4の過剰投稿を防ぐための最良の方法は何ですか?

MSの情報源によると、[Bind]属性は、受信フォームの値がデータベースに到達しないようにすることで、過剰投稿を防ぐ最も簡単な方法であると考えられています。最新バージョンのMVC&EFでは、何か大きなものが欠けていない限り、これは期待どおりに機能していないようです。

Wrox Professional ASP.NET MVC 4(Jon Gallowayの第7章)から、次のクラスで過剰投稿を防ぐ必要があります。

[Bind(Exclude="IsAdmin")]
public class User
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public bool IsAdmin { get; set; }
}

ただし、[Bind]属性が行うのは、フォーム送信値がモデルにバインドされないようにすることだけです。モデルには空白/デフォルト値があり、データベースに書き戻されます。この場合、このモデルを使用して.SaveChanges()を呼び出すたびに、IsAdmin=falseになります。「真の」値はすべて上書きされます。それは巨大なセキュリティ障害です。

別の構文([Bind]を[コントローラーの編集]アクションパラメーターに配置する]は、まったく同じことを行います。

public ActionResult Edit([Bind(Exclude = "IsAdmin")] User user)

.SaveChanges()が呼び出されると、すべての「true」値が上書きされます。これは、このトピックに関するK. Scott Allenのブログ投稿(http://odetocode.com/blogs/scott/archive/2012/03/11/complete-guide- )と矛盾します。 to-mass-assignment-in-asp-net-mvc.aspx

唯一の選択肢は、すべてAutomapperに接続された専用のViewModelの急増であるようです。安全ではありますが、それは特に次のような大きな頭痛の種のようです。

  • 作成、編集、インデックス作成、および詳細アクションの要件が異なる場合があり、異なるViewModelが必要になります
  • 作成アクションによって更新されるため、プロパティに[読み取り専用]属性を持つことができない一部の読み取り専用フィールド(編集アクションのCreatedByなど)を公開する必要がある場合があります。

データモデルをビューにバインドしてはいけないと誰かが答えるのは知っていますが、これがデフォルトのテンプレートの動作であり、ほぼすべてのドキュメントに示されている方法です。さらに、MVC + EFは、困難ではなく、生活をにするはずでした。AutoMapperに接続されたModelViewクラスの海は、私が簡単だとは思っていません。

では、[Bind]を宣伝どおりに機能させる方法を知っている人はいますか?

4

2 に答える 2

7

今回はWroxの本で誤解を招くかもしれませんね。説明するのは、Bind/Excludeプロパティの意図された動作です。http://msdn.microsoft.com/en-us/library/system.web.mvc.bindattribute.exclude(v=vs.108).aspxを参照してください。

モデルのすべてのプロパティに値をバインドしたくない場合は、ViewModelsが適切な方法であると思いますが、正しく指摘しているように、これらはオーバーヘッドのようなものです。それにもかかわらず、それらを使用することの利点は重要であり、この種のコンテキストでのIMOは、追加の開発作業を正当化します。例えば:

  • エンティティの部分的な更新を許可する
  • 複数のエンティティからのデータを提示する
  • UIをドメインモデルから切り離し、ラベル、検証ルール、エラーメッセージを変更できるようにします

Automapperは、エンティティからモデルを表示するためのマッピングを行うための1つのオプションですが、遅延読み込みを使用している場合は注意してください。AutomapperがEFプロキシクラスの更新を期待どおりに処理しないことを発見しました。最終的に、AMを削除し、IMappableインターフェイスと汎用ユーティリティクラスに基づいて独自のマッピングメカニズムを導入しました。多くの場合、Automapperを構成するよりも、それを行うために入力するコードの方がはるかに多くありません。

于 2012-11-24T06:52:49.687 に答える
0

マヌエルモデルバインディングに戻せば、問題はないはずです。「IsAdmin」の入力を行わない場合、モデルは元の値を保持します。これにより、数行の余分なコードが追加されますが、ViewModelsを維持せずに生成しないため、多くの時間を節約できます。

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Guid id, FormCollection collection)
{
    var user = db.Users.Find(id);
    if (user != null)
        TryUpdateModel(user);
    else
        return HttpNotFound();
    if (ModelState.IsValid)
    {
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(user);
}
于 2013-07-31T21:01:32.443 に答える