4

多くのユーザー コントロールで構成されたページがあります。このページのビュー モデルはかなり複雑です。

public class ComplexViewModel
{
    public ObjectA ObjectAProperty { get; set; }
    public List<Things> ListOfThings { get; set; }
    public List<ThingCategories> ListOfThingCategories { get; set; }
    public List<ThingTypes> ListOfThingTypes { get; set; }
    public List<ThingOptions> ListOfThingOptions { get; set; }
    public int ChosenThingCategoryId { get; set; }
    public int ChosenThingTypeId { get; set; }
    public int ChosenThingOptionId { get; set; }
    public OtherObject ObjectData { get; set; }
}

このページには、フィルタリング、ソートなどの情報を含む PostModel もあります。

    public class SimplePostModel
{
    public int ChosenThingCategoryId { get; set; }
    public int ChosenThingTypeId { get; set; }
    public int ChosenThingOptionId { get; set; }
    public int ChosenThingFilterTypeId { get; set; }
    public int ChosenThingSortTypeId { get; set; }
    public int ChosenThingOtherId { get; set; }
    public int ChosenThingMoreId { get; set; }
    public int ChosenThingOMGId { get; set; }
}

単純な PostModel が検証された後、コントローラーは 3 つ以上のリポジトリを開き、それぞれに複数の呼び出しを行い、ビュー モデルを構築します。控えめに言っても、私のコントローラー アクションはかなり大きくなりました。

これは私が取り組んできた中で最も複雑なページであり、よりシンプルにする方法を決めるのに苦労しています.

私が最初に考えたのは、バインディングの検証後にリポジトリを呼び出して ViewModel を返すビュー モデル ファクトリを作成することでした。

次に、PostModel を検証し、ViewModel を 1 ステップでハイドレートするカスタム モデル バインダーを作成することを考えました。

私の質問は、複雑なビュー モデルをどのようにハイドレートするかということです。

これを書いているうちに、Html.RenderAction を使用して、ページという野獣を構成する各ユーザー コントロールのモデルを作成するというアイデアが浮かびました。

アップデート:

リポジトリは WCF サービスを呼び出し、アプリケーションはより大きな SOA アーキテクチャの一部です。

4

1 に答える 1

6

いくつかの一般的なヒント。データは、システム スコープ、セッション スコープ、リクエスト スコープなど、いくつかのカテゴリに分けることができます。

システム スコープ データは、ユーザーに提示する必要があるデータですが、ユーザーごとに同じです。ブログ アプリケーションの例としては、タグ クラウドやカテゴリのリストがあります。このデータは、ユーザーの操作とは関係がないため、コントローラーまたはアクションを介して流れる必要はないと主張します。ビュー自体は、このデータを取得 (できればキャッシュ) する方法を知っている HtmlHelper (または LayoutDataHelper) を呼び出すことができます。

セッション スコープ データは、ViewData.Model のフィールドに入力する ActionFilters で処理できます。アクションのパラメーターとは直接関係ありません。たとえば、ユーザー名です。フォームの属性を好む

public class SessionDataFilter : ActionFilter 
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result is ViewResult)
        {
            var view = filterContext.Result as ViewResult;

            // hydrate session data on view.ViewData.Model
        }
    }
}

リクエストスコープ/固有のものはすべて、アクションに入力する必要があります。ただし、これは、それを行うために 1 つの大規模なアクション メソッドが必要であるという意味ではありません。ViewModels がどのように構成されているかを確認します。あなたが示唆したように、入力が必要なコントロールがある場合、ViewModel の情報を関連するセットにグループ化できる可能性があります。そのため、他の小さなビュー モデル (「部分ビュー モデル」) を構成するだけの ViewModel がある場合があります。次に、ロジックを分解して、各部分ビュー モデル (およびその他の複雑なロジック) をそれぞれ独自の再利用可能で分離されたメソッドに設定します。

投稿を扱う場合も同様の抽象化が適用されますが、関連のないデータを多数投稿するページの使いやすさが心配になります。ActionFilters( OnActionExecuting) を使用して、関連する着信データのセットを解析し (およびオプションで検証)、それらをアクション パラメーターに割り当てることができるはずです。同じデータのセットが複数のアクションに投稿され、受信データの形状が常に同じでない限り、投稿されたデータのバインダーよりもフィルターを好みます。

幸運を。

于 2010-01-20T06:15:36.023 に答える