4

私は、ASP.NET MVC 3 用の小さなライブラリに取り組んでいます。これにより、モデル メタデータの再利用性が向上し、データ エンティティからカスタム ビューモデルへのマッピングが容易になります。このためには、ASP.NET MVC の 3 つの異なる関心領域に対して ICustomTypeDescriptor の独自の実装を提供できる必要があります。

  1. 足場
  2. 検証
  3. モデルバインディング

System.Web.Mvc.ModelMetadataProviders.Currentこれは、独自の CustomMetaDataProvider に設定することで実行できるようです が、上記の 3 つのポイントすべてをカバーするには、これでは十分ではありません。

問題は、System.Web.Mvc にいくつかのクラスがあり、これを直接呼び出すことSystem.Web.TypeDescriptorHelperです。これは次のようになるため、拡張できません。

internal static class TypeDescriptorHelper {
        public static ICustomTypeDescriptor Get(Type type) {
            return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
        }
    } 

私が見つけた唯一の解決策は非常に扱いにくく、それを機能させるには System.Web.Mvc から多くの型をサブクラス化する必要がありました。CustomModelBinderDictionary1 ~ 2 行のコードを上書きするためだけに、完全に再実装する必要さえありました。したがって、機能しますが、非常に厄介なハックであり、次に新しい ASP.NET MVC バージョンに更新するときに壊れる可能性があります。

だからここに私が知りたいことがあります:これを行う簡単な方法を見逃しましたか?

おまけの質問: MVC チームのメンバーでなく、MVC 4 で適切な拡張ポイントを作成することを検討していただけないでしょうか ;-)?

編集:独自の TypeDescriptor をコーディングする必要がある理由の質問への回答: これにはいくつかの理由があります: 1. 最も重要: https://forums.asp.net/t/1614439で説明されている問題の回避策が必要です.aspx/1 2. また、さまざまな理由からメタデータを動的に挿入する必要があります。たとえば、独自の Bind 属性をコーディングしたいのですが、BindAttribute はシールされています。したがって、そこから派生するのではなく、独自のバインド属性の実装を検出するときに、一致する BindAttribute を TypeDescriptor から動的に発行しています。

4

2 に答える 2

1

Brad Wilson (ASP.NET MVCチームメンバー)によると、この問題はMVC 4のバグリストに追加されています。したがって、現時点では適切な解決策はないようですが、MVC4がリリースされたときに解決されることを願っています。

再利用可能な検証とスキャフォールディングメタデータおよびモデル/ビューモデルマッピングのために私のライブラリに興味がある人は、 https: //devermind.wordpress.com/で私のブログを購読してください。そこでライブラリをリリースします。

于 2011-04-29T08:49:07.260 に答える
0

MVC の DependencyResolver 機能では実行できない Validation、ModelBinding、および潜在的に ModelMetadata のカスタム実装で何をしようとしているのかわかりませんか?

MVC 3 の最近のツール更新での新しいスキャフォールディング サポートは、スキャフォールディングのニーズを満たす場合があります。ただし、ModelBinding、ModelMetadata、および Validation の DependencyResolver 機能にフックする可能性を調べて、探しているものを達成できるかどうかを確認します。私は最近、柔軟なフレームワークを提供するために、これらの動作の多くをゼロから実装する必要があり、IoC を使用する ModelMetadata と Validation プロバイダーだけでそれを行うことができました。また、柔軟性をさらに高めるために、いくつかのケースで DynamicObject (または ExpandoObject) を継承することになりました。これが直接的な答えではないことはわかっていますが、これらの拡張ポイントよりも低いものにアクセスする必要がある理由がわかりません。

編集:複数の場所で同じ ModelMetadata を再定義する必要がないように、類似の ViewModel で ModelMetadata を再利用することを検討している場合は、この影響を考慮する必要があります。エンティティに特定のデータ制限が必要な場合はよくありますが、これらの制限は ViewModel ではなく DataModel に適用する必要があります。ユーザーには、もう少し制限の厳しいルールが設定されている場合があります。たとえば、特定のフィールドが ViewModel のユーザーに対して読み取り専用であることを規定できますが、DataModel として使用されるエンティティでは (通常はコード内から) 値を変更できます。同様に、VideModel の Create ビューを生成するために使用される ModelMetadata が、Edit ビューに使用される ViewModel とわずかに異なる場合があります。それらを再利用することは、一貫性を保ち、コードの重複を減らすための優れた方法のように思えるかもしれませんが、後で後悔することになるかもしれません. 私は最近、ポストバックを引き起こす可能性のあるビューごとに新しい ViewModel を作成することを避けたいという同じ問題に遭遇しました。好きな完璧な解決策は見つかりませんでしたが、ModelMetadata を再利用すると、解決できる可能性のあるより多くの問題が発生すると思います私の意見。ViewModels を必要とするビュー用に ViewModels を記述すると、カスタム BindAttribute 実装を実装する必要がなくなり、Scaffolding の問題も解消される可能性があります。独自のメタデータを使用して非常に多くの ViewModel を作成したくないと想定しているのが正しいとすれば、カスタム BindAttribute、カスタム Scaffolding、カスタム ModelMetadata、カスタム Validation、およびカスタム ModelBinding の実装を見つけようとする原因です...

より良いアプローチを見つけた場合は、お気軽にお知らせください:-)

于 2011-04-26T19:22:45.730 に答える