クライアントとの対話の両方向にViewModelという用語を再利用していると言いたいです。十分な数のASP.NETMVCコードを実際に読んだことがある場合は、ViewModelとEditModelの違いを見たことがあるでしょう。それは重要だと思います。
ViewModelは、ビューのレンダリングに必要なすべての情報を表します。これには、静的な非対話型の場所でレンダリングされるデータや、純粋にチェックを実行して何を正確にレンダリングするかを決定するためのデータが含まれる可能性があります。コントローラのGETアクションは、通常、ビューのViewModelをパッケージ化する役割を果たします。
EditModel(またはおそらくActionModel)は、ユーザーがそのPOSTに対して実行したいアクションを実行するために必要なデータを表します。したがって、EditModelは実際にアクションを記述しようとしています。これにより、ViewModelから一部のデータが除外される可能性があります。関連はありますが、実際には異なることを理解することが重要だと思います。
1つのアイデア
つまり、[モデル]-> [ViewModel]から移動するためのAutoMapper構成と、[EditModel]-> [モデル]から移動するための別の構成を非常に簡単に作成できます。次に、さまざまなコントローラーアクションでAutoMapperを使用する必要があります。EditModelには、モデルに対してそのプロパティを検証し、それらの値をモデル自体に適用するための関数が含まれている可能性があります。それは他に何もしていません、そしてあなたはとにかくリクエストをEditModelにマップするためにMVCにModelBindersを持っています。
別のアイデア
私が最近考えていることを超えて、ActionModelのアイデアからそのようなものが機能するのは、クライアントがあなたに投稿しているのは、実際にはユーザーが実行したいくつかのアクションの説明であり、1つの大きなデータの塊ではないということです。これには確かにクライアント側で管理するためのJavascriptが必要ですが、そのアイデアは興味深いと思います。
基本的に、ユーザーが提示した画面でアクションを実行すると、Javascriptはアクションオブジェクトのリストの作成を開始します。例としては、ユーザーが従業員情報画面を表示している可能性があります。従業員が最近結婚したため、姓を更新し、新しい住所を追加します。カバーの下で、これはリストへのChangeEmployeeName
とAddEmployeeMailingAddress
オブジェクトを生成します。ユーザーが[保存]をクリックして変更をコミットし、2つのオブジェクトのリストを送信します。各オブジェクトには、各アクションの実行に必要な情報のみが含まれています。
デフォルトのものよりもインテリジェントなModelBinderが必要ですが、優れたJSONシリアライザーは、クライアント側のアクションオブジェクトからサーバー側のアクションオブジェクトへのマッピングを処理できるはずです。サーバー側のもの(2層環境にいる場合)は、それらが動作するモデルでアクションを完了するメソッドを簡単に持つことができます。したがって、Controllerアクションは、モデルインスタンスがプルするIDと、それに対して実行するアクションのリストを取得するだけになります。または、アクションにIDを含めて、アクションを非常に分離します。
したがって、おそらくこのようなものがサーバー側で実現されます。
public interface IUserAction<TModel>
{
long ModelId { get; set; }
IEnumerable<string> Validate(TModel model);
void Complete(TModel model);
}
[Transaction]
public ActionResult Save(IEnumerable<IUserAction<Employee>> actions)
{
var errors = new List<string>();
foreach( var action in actions )
{
var employee = _employeeRepository.Get(action.ModelId);
errors.AddRange(action.Validate(employee));
}
foreach( var action in editModel.UserActions )
{
var employee = _employeeRepository.Get(action.ModelId);
action.Complete(employee);
_employeeRepository.Update(employee);
}
}
ModelBinderを使用して正しいIUserActionインスタンスを取得し、IUserActionインスタンスを使用して正しいロジック自体を実行するか、(おそらく)情報を使用してモデルを呼び出すため、ポストバックアクションはかなり一般的なものになります。
3層環境にいる場合、IUserActionを単純なDTOにして、境界を越えてショットし、アプリ層で同様の方法で実行することができます。そのレイヤーの実行方法によっては、非常に簡単に分割でき、トランザクションに残る可能性があります(頭に浮かぶのは、Agathaの要求/応答であり、DIとNHibernateのIDマップを利用しています)。
とにかく、それは完璧なアイデアではないと確信しています。管理するにはクライアント側のJSが必要であり、プロジェクトがどのように展開するかを確認することはまだできていませんが、投稿はその方法を考えようとしていました。そこに行ってまた戻ってくるので、私は自分の考えを述べると思いました。それがお役に立てば幸いです。相互作用を管理する他の方法について聞いてみたいと思います。