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