8

現在、ViewModel を使用して、ビューを実際のモデル構造から分離しています。

たとえば、ユーザー永続エンティティと、ユーザーが自分で変更できるすべての情報を含む MyProfile ViewModel があります。User から MyProfile への変換には、Automapper を使用しています。

ユーザーが自分の (変更された) 情報を投稿した後、これらを保存する必要があります。しかし、ViewModel の情報は完全ではなく、AutoMapper が ViewModel から User 永続エンティティを作成すると、重要な情報が失われます。

特に非表示のフォーム要素では、この情報をビュー レイヤーに公開したくありません。

したがって、ViewModel を永続エンティティにマージする方法が必要です。AutoMapper でそれを行うことはできますか、それとも手動で行う必要がありますか?

例:

私の User クラスには、ID、Firstname、Lastname、Username、および Password が含まれています。ユーザーは、自分のプロファイルで自分の名と姓のみを編集する必要があります。したがって、私の ProfileViewModel には ID、Firstname、Lastname が含まれています。フォームから情報をポストバックした後、Automapper は転送された ProfileViewModel から User オブジェクトを作成し、このオブジェクトには ID、Firstname、Lastname のみが設定されます。このエンティティをリポジトリにフィードするときに、ユーザー名とパスワードの情報を失いました。

4

1 に答える 1

12

したがって、ViewModel を永続エンティティにマージする方法が必要です。AutoMapper でそれを行うことはできますか、それとも手動で行う必要がありますか?

はい、AutoMapper でそれを行うことができます。例えば:

public class Model
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ViewModel
{
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        // define a map (ideally once per appdomain => usually goes in Application_Start)
        Mapper.CreateMap<ViewModel, Model>();

        // fetch an entity from a db or something
        var model = new Model
        {
            Id = 5,
            Name = "foo"
        };

        // we get that from the view. It contains only a subset of the
        // entity properties
        var viewModel = new ViewModel
        {
            Name = "bar"
        };

        // Now we merge the view model properties into the model
        Mapper.Map(viewModel, model);

        // at this stage the model.Id stays unchanged because
        // there's no Id property in the view model
        Console.WriteLine(model.Id);

        // and the name has been overwritten
        Console.WriteLine(model.Name);
    }
}

プリント:

5
bar

これを典型的な ASP.NET MVC パターンに変換するには:

[HttpPost]
public ActionResult Update(MyViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        // validation failed => redisplay view 
        return View(viewModel);
    }

    // fetch the domain entity that we want to udpate
    DomainModel model = _repository.Get(viewModel.Id);

    // now merge the properties
    Mapper.Map(viewModel, model);

    // update the domain model
    _repository.Update(mdoel);

    return RedirectToAction("Success");
}
于 2012-04-23T07:52:06.370 に答える