web-dev-qa-db-ja.com

TryUpdateModelの実際の例、ASP .NET MVC 3

TryUpdateModelの使用方法とMVCアーキテクチャの保存方法を同時に理解できません。

間違っていない場合は、データコンテキストをモデルに含める必要があります。だから、そのようなコード

var db=new TestEverybody();//it is class, which was generated by EntityFramework 
var currentTesting=db.Testing.(t => t.id == id).First();

コントローラーではなくモデルに配置する必要があります。

ただし、TryUpdateModelの通常の使用例は次のとおりです。

    public ActionResult Edit(Testing obj)//Testing collection
    {
        var db = new TestEverybody();
        var currentTesting=db.Testing.(t => t.id == obj.id).First();
        TryUpdateModel(currentTesting);
        db.SaveChanges();            
        return RedirectToAction("Index");
    }

この方法はMVCアーキテクチャを破壊しませんか?特別なModelクラスではなく、コントローラーでデータベースを操作します。

それでは、実際のプロジェクトでTryUpdateModelを使用する最良の方法は何ですか?

29
Sir Hally

OPが尋ねたので、ViewModelパターンの例、または私がそれを呼び出すのが好きなもの-ASP.NET MVCが適切に行われました。

なぜビュー固有のモデルを使用するのですか

  1. ビューに必要な情報のみを渡す必要があります。
  2. 多くの場合、追加のビューメタデータ(タイトル/説明の属性など)を追加する必要があります。これらはあなたのエンティティに属していません。
  3. TryUpdateModel/UpdateModelの使用は間違っています。使用しないでください(理由を説明します)。
  4. ビューモデルがエンティティと完全に一致することは非常にまれです。多くの場合、人々はエンティティに追加のデータを追加するか、厳密に型指定されたビューモデルプロパティではなく、単にViewBagを使用します。
  5. ORMを使用している場合、遅延読み込みプロパティ(N + 1)で問題が発生する可能性があります。ビューでクエリを発行しないでください。

単純なエンティティから始めます。

public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public decimal Price {get;set;}
}

そして、ユーザーがonly製品のNameDescriptionを更新できるシンプルなフォームがあるとしましょう。しかし、あなたは(非常に貪欲な)TryUpdateModelを使用しています。

したがって、私は任意の数のツール(Fiddlerなど)を使用してPOST自分を作成し、以下を送信します。

Name = WhatverIWant&Description = UnluckyFool&Price = 0

ASP.NET MVCモデルバインダーは入力フォームコレクションを検査し、これらのプロパティがエンティティに存在することを確認し、自動的にバインドします。したがって、データベースから取得したばかりのエンティティで「TryUpdateModel」を呼び出すと、一致するすべてのプロパティが更新されます(Price!を含む)。新しいオプションの時間。

特定のモデルを表示

public class EditProductViewModel {
    [HiddenInput]
    public Guid Id {get;set;}

    [Required]
    [DisplayName("Product Name")]
    public string Name {get;set;}

    [AllowHtml]
    [DataType(DataType.MultilineText)]
    public string Description {get;set;}
}

これには、ビューに必要なプロパティのみが含まれています。いくつかの検証属性、表示属性、およびmvc固有の属性も追加していることに注意してください。

ビューモデルにあるものに制限されないことにより、ビューをよりきれいにすることができます。たとえば、ビューに次のものを含めることで、編集フォーム全体をレンダリングできます。

@Html.EditorFor(model => model)

Mvcは、ビューモデルに追加したすべての属性を検査し、検証、ラベル、および正しい入力フィールド(説明用のテキストエリア)を自動的に結び付けます。

フォームの投稿

[HttpPost]
public ActionResult EditProduct(EditProductViewModel model) {

    var product = repository.GetById(model.Id);

    if (product == null) {
        return HttpNotFound();
    }

    // input validation
    if (ModelState.IsValid) {

        // map the properties we **actually** want to update
        product.Name = model.Name;
        product.Description = model.Description;

        repository.Save(product);

        return RedirectToAction("index");
    }

    return View(model)
}

このコードから、それが何をするかはかなり明らかです。エンティティのプロパティを明示的に設定しているため、エンティティを更新するときに望ましくない影響はありません。

これでView-Modelパターンが十分に説明できると思います。

114
Ben Foster

したがって、そのようなコードは、コントローラーではなくモデルに配置する必要があります。

必ずしも。個人的には、データアクセスコードをリポジトリに配置することを好みます。次に、コンストラクター注入を使用して、特定のリポジトリー実装をコントローラーに渡します(例えば、EFを使用している場合、EFリポジトリー実装を作成します)。したがって、コントローラーは次のようになります。

public class HomeController: Controller
{
    private readonly IMyRepository _repository;
    public HomeController(IMyRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Edit(int id)
    {
        var currentTesting = _repository.GetTesting(id);
        TryUpdateModel(currentTesting);
        _repository.SaveChanges();            
        return RedirectToAction("Index");
    }
}
19
Darin Dimitrov