問題タブ [modelmetadata]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
asp.net-mvc - 動的オブジェクトの MVC3/4 セキュリティとモデル バインディング
私は本当にこれについて 2 番目の目を必要としているので、あなたの何人かが私にフィードバックをくれることを願っています。
ASP.NET MVC3 を使用して Web サイトをセットアップしようとしていますが、このサイトでは動的オブジェクトを作成する柔軟性が必要です。しかし、私のデータベースには、これらの動的オブジェクトに含まれる構造とデータに関する情報を格納する一連のテーブルが設定されているということです。既存のデータベースを使用しているため、変更できる内容が (ある程度) 制限されています。データベースに動的オブジェクト (.NET 4.0 の動的オブジェクトではない) を照会すると、ID を渡すと返されるのは、内部使用のみを目的とした少数のプロパティを持つ単純なオブジェクトと、動的オブジェクトのすべてのプロパティを含むコレクションであるプロパティ。したがって、動的オブジェクトが名前、生年月日、および性別を持つ人物用である場合、コレクションには各プロパティに 1 つずつ、合計 3 つのオブジェクトが含まれます。これにより、サイトの管理者は実行時に新しいフィールドを追加でき、Web サイトはそれらを自動的にレンダリングし、更新などを許可します。現在、このデータ構造の表示とポストバックの両方でモデル バインディングが機能しています。コレクション内の各オブジェクトについて、私はプロパティの一意の ID (現在は隠しフィールドであり、ID は Guid です) とプロパティの値の 2 つのデータをレンダリングします。私の問題はセキュリティ面です。
厳密に型指定されたオブジェクトを扱っている場合、カスタム ViewModel を作成してそれを処理するか、アクションのシグネチャに Bind() 属性を追加できますが、これらのオブジェクトのプロパティは柔軟なコレクションであるため、どのようにアプローチすればよいかわかりません。アクション レベルのセキュリティは非常に単純です。カスタム Authorize 属性を作成し、データベースにアクセス許可を問い合わせることができますが、ユーザー アクセス許可に基づいて情報を表示および受け入れるためのコレクションの動作を制限できるようにする必要があります。たとえば、社会保障番号のプロパティを person オブジェクトに追加する場合、特定の人の画面に表示したくありません。ただし、プロパティは実行時に変更できるものであるため、アクセス許可も変更できます。
私の考えが進む限り、私はここにいます...
そのため、ユーザーのアクセス許可に応じて、プロパティのコレクション内のどのオブジェクトを画面にレンダリングしたり、ポストバック時にバインドしたりできるかを判断する方法が必要です。オブジェクトを表示するには、ViewModel オブジェクトにアクセス許可を何らかの方法で含め、プロパティのコレクションで使用されるオブジェクト タイプを対象とした DisplayTemplate でこれらのアクセス許可を照会する以外に、選択肢はあまりないと思います。または、Html.Display() および Html.Editor() の呼び出しに使用されるカスタム ModelBinder を作成し、ModelBinder 内のリストのフィルタリングを調べることもできます。
ただし、ポストバックについても同様の問題があります。それがポストバックされると、Guid と値のみを含むデータのコレクションが返されます。ただし、ユーザーが独自のフィールドをフォームに挿入していないことを確認する必要があります。また、アクションに返されるプロパティについて、ユーザーが適切な権限を持っていることも確認する必要があります。理想的には、このチェックを Model Binding に統合し、可能であれば MetaData から入力された情報の一部を再利用して、渡されたデータを単純に無視して、ユーザーが変更する権利を持たないようにしたいと考えています。これに失敗した場合は、ポストバックを処理するアクションの開始時に行われる IsValid チェックで、ユーザーが設定しようとしているすべての属性にアクセスできることを確認します。
次に、データベース内の情報に基づいて各プロパティの Html.Display() および Html.Editor() への呼び出しで使用する MetaData の動的な構築があります。データ注釈。
問題は、ModelBinders、ModelMetaDataProviders、ModelValidationProviders などのデフォルトの実装をオーバーライドすることに関して、MVC の内部に精通していないことです。
私が説明していることを達成するために考えられる最善の方法についていくつかの提案を提供できますか、またはこの例をカバーする他の記事を知っている場合は、それらを見てみたいと思います.Googleであまり運がありません.これまでのところ、この特定の主題について。
編集:私がしたことの詳細については、以下の私の回答を参照してください
編集: メタデータ プロバイダーが動作するようになりました。独自のクラスを実装し、ModelMetadataProvider から継承する必要がありました。
最初の部分は一目瞭然で、まず、データの取得元の列名に最も近い .NET 型を渡すことによって GetMetadataForType() でメタデータを設定します。(私のエディター teplate は、このデータを定義するデータ構造で定義されているように、データがどの列にあるかを動的に選択することでこれを支援します)
扱うのは少し奇妙ですが、私が言ったように、それは既存のデータ構造です。
switch ステートメントの後で、おかしくなりました。私が理解しているように、MVC2 では、GetMetadataForProperty()メソッドは Model 自体をパラメーターとして取得せず、 を使用してプロパティを見つけます。代わりに、MVC がメタデータを必要とするプロパティを指すpropertyName型の式を渡します。Func<object>ルート モデルで別のプロパティを使用して構造の詳細を決定する必要があったため、これには問題がありました。ここで、リフレクションを使用してモデルを取得できるという別の解決策を見つけましたが、それにはリフレクションが必要です。私が望んでいたものではありませんが、うまくいきます。モデルを取得したら、これまでのメタデータとモデルを作成したメソッドに渡し、MVC がそこから使用AddSupplimentalMetadata()するオブジェクトの残りのプロパティを設定します。DataAnnotationsModelMetadata
次に、ユーザーのアクセス許可に応じて、特定のプロパティをレンダリングするかレンダリングしないかを動的に選択する方法を見つけ出す必要があります。私がしなければならないことは、モデルをビューに渡す前に、LINQ などを使用して、プロパティのリストをフィルター処理することだと思います。ビジネス ロジックを Display/EditorTemplate に入れるという考えは好きではありません。変更を保存するには、検証システムを調べて、ユーザーが情報を渡そうとしているプロパティを検証するためにそれにフックできるかどうかを確認する必要があります。
asp.net-mvc - asp.net mvc の editortemplate の複合型の ModelMetadata
次のように宣言されている TestThing 型の複雑なプロパティを含むビューモデルがあります。
各子プロパティのメタデータにアクセスできるようにしたい、このタイプの EditorTemplate があります。たとえば、テンプレートが文字列の場合、 を使用して Prompt テキストにアクセスできます@ViewData.ModelMetadata.Watermarkが、複雑な型であるため、このメソッドを使用することはできません。
代替手段はありますか?
asp.net - asp.net mvc3Html.GetUnobtrusiveValidationAttributesとネストされたモデル
これが状況です。ネストされた複雑なモデルタイプを含むViewModelがいくつかあります。モデルの1つのスニペットを次に示します(これは完全なクラスではありません)。
そして、ContactModelクラスからのスニペット(完全ではありません):
私の問題は、クライアント側の検証のために、ネストされたモデルタイプであるContactModelから検証属性を取得できる必要があることです。* For()ヘルパーメソッドを使用しないため、ほとんどのビューで手動アプローチを使用します。これが私がすることです:
これはチャンピオンのように機能し、ビューのモデルが「検証」属性が適用されているモデルである場合にのみ、モデルから期待される検証属性を生成します。 「検証」属性を持つモデルがネストされたモデルオブジェクト内にある場合、これは機能しません。このシナリオの検証属性を取得する方法を理解しようと苦労しています。ビューは複雑で、モデルの複数のビューにそれ以上分解できないため、ネストされたモデルで動作する必要があります。
私は多くのアプローチを試みましたが、汚染されていない答えを得るためにまだそれらに入るつもりはありません。バインディングプレフィックスを使用し、静的な「ModelMetadata」クラスのいくつかを調べてネストされたモデル構造にドリルインしようとしましたが、現時点ではうまくいきません。どんな助けでも大歓迎です。
他に何が必要か教えてください。
ブラッド・ウィルソンのブログ投稿や彼の領域の他の人たちもたくさん読んだことがありますが、今のところ運がありません。
asp.net-mvc-3 - ASP.NETMVC3データ属性-コントローラーからプログラムでUIHintを設定する
私がこのようなViewModelを持っている場合:
そして、EditorForを使用してフォームフィールドをレンダリングします。
レンダリングされます<input type="text">。涼しい。
しかし、この特定のシナリオでは、私はすでに別のソースから電子メールを取得しており、フォームにこのデータを事前に入力し、テキストボックスの代わりにラベルを表示したいと思います(電子メールを変更したくないため-理由は気にしないでください)。
使用できることはわかって[UIHint]いますが、コントローラーからプログラムで使用できますか?
例えば:
これにアプローチするための最良の方法は何ですか?別のViewModelを完全に使用する必要があります。これは、ビューを強い型から強い型に変更することを意味する可能性がありますか、dynamic使用しないEditorForか、カスタムエディターテンプレートを使用する必要がありますか?
提案/アドバイスをいただければ幸いです。
asp.net-mvc - ASP.NET MVC で独自の ICustomTypeDescriptor を提供するにはどうすればよいですか?
私は、ASP.NET MVC 3 用の小さなライブラリに取り組んでいます。これにより、モデル メタデータの再利用性が向上し、データ エンティティからカスタム ビューモデルへのマッピングが容易になります。このためには、ASP.NET MVC の 3 つの異なる関心領域に対して ICustomTypeDescriptor の独自の実装を提供できる必要があります。
- 足場
- 検証
- モデルバインディング
System.Web.Mvc.ModelMetadataProviders.Currentこれは、独自の CustomMetaDataProvider に設定することで実行できるようです が、上記の 3 つのポイントすべてをカバーするには、これでは十分ではありません。
問題は、System.Web.Mvc にいくつかのクラスがあり、これを直接呼び出すことSystem.Web.TypeDescriptorHelperです。これは次のようになるため、拡張できません。
私が見つけた唯一の解決策は非常に扱いにくく、それを機能させるには 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 から動的に発行しています。
custom-attributes - CreateMetadata を使用して ModelMetadata をカスタマイズする
ユーザーが選択リストから値を初めて選択すると、テキストPick oneと値を含むデフォルト オプションが表示されます-1。
これを支援するために、カスタム属性がありますNotEqualAttribute。ドロップダウン リストが必要な場合は、正しく機能させるために両方の属性を使用する必要があります。
VM は次のようになります。
これを使用することをお勧めします:
別の StackOverflow の質問では、プロパティが明示的に設定されていない限り、null 非許容プロパティをオプションRequiredにする方法について説明しています。
これを実行しようとしましたが、新しい属性をIEnumerable<Attribute>コレクションに追加する方法やModelMetadata、メタデータ プロバイダーに追加する方法がわかりません。
c# - Entity Framework - エンティティからテーブル名を取得する
Code First アプローチで Entity Framework 4.1 を使用しています。エンティティのストレージ モデル タイプと列名を取得できます。
私が必要とするのは、エンティティがマップされている実際のテーブル名を取得することです。それを指定するには、さまざまな方法があります (Fluent-API .ToTable()、DataAnnotation [TableAttribute] を使用)。
この情報を取得する一般的な方法はありますか?
asp.net-mvc-3 - コントローラーから AdditionMetadata 属性を取得するにはどうすればよいですか?
一部のクラス、たとえばクラス A には、(タイプ B の) プロパティがあります。
その後、コントローラーで、このクラスをインスタンス化し、モデルにします。
後で、クラス B のカスタム エディター テンプレート (つまり、部分ビュー) ができました。そこから、AdditionalMetadata を次の方法で取得できることがわかります。ViewData.ModelMetadata.AdditionalValues["foo"];
しかし:コントローラーから、そのメタデータ プロパティを以前に取得する方法はありますか?
c# - モデル メタデータを取得する HtmlHelper メソッドの一貫性のない動作
モデルのメタデータを取得する方法に関係する、MVC3 の予期しない動作を追跡しています。
システムの 2 つの異なる領域で収集される一部のデータに同じ EditorTemplate を使用することについて、開発者の 1 人と以前に話しました。[必須] 属性を除いて、データ フィールドはほとんど同じです。あるページでは特定のフィールドが必須であり、別のページでは必須ではありません。理論的には、これは、各フィールドに共通の属性を持つ基本モデルを使用し、それらのモデルを継承し、プロパティをオーバーライドし、追加の検証属性を追加することで実現できます。例えば:
次に、View を BaseModel に厳密に型指定できます。ビューで @Html.EditorFor(m=>m.MyLabel) を呼び出すと、モデルの実際のインスタンスが BaseModel であるか RequiredModel であるかに応じて、正しい属性が取得されます。
それが理論です。
実際、@Html.TextBox(“MyLabel”) などの「古い」HTML ヘルパーを使用すると、うまく機能します。これらは ModelMetadata.FromStringExpression(field) を呼び出します。具体的なモデル インスタンスが RequiredModel の場合、RequiredModel からメタデータを正しく取得します。新しいヘルパー メソッドは ModelMetadata.FromLambdaExpression(expression) を呼び出しますが、これは正しい具象インスタンスからメタデータを正しく取得しません。
これは MVC のバグですか? 意図的な行動?この問題に対処するための回避策またはより良い方法はありますか?
これはもちろん些細な例です。私たちが扱っている実際のコードには、いくつかの複雑なビジネス ルールと相互作用を持つ約 20 のフィールドがあり、フィールドが必要な場合を除いて、両方のページで同じです。
c# - ModelMetaData、カスタム クラス属性、および説明のつかない質問
私がやりたいことはとてもシンプルに思えます。
私のindex.cshtmlにWizardStepAttribute値を表示したい
ユーザーは各ページの上部にStep 1: Enter User Information
というViewModelがありWizardViewModelます。このViewModelには次のプロパティがありますIList<IStepViewModel> Steps
各「ステップ」は、空のインターフェイスである Interface IStepViewModel を実装します。
Index.cshtml というビューがあります。このビューにはEditorFor()、現在のステップが表示されます。
プロパティIStepViewModelに基づいて実装する具象クラスの新しいインスタンスにビューをバインドするカスタム ModelBinder があります。WizardViewModel.CurrentStepIndex
カスタム属性を作成しましたWizardStepAttribute。
私の各 Steps クラスはこのように定義されています。
しかし、いくつかの問題があります。
WizardViewModel私のビューは、各ステップではなく強く型付けされています。具体的な実装ごとにビューを作成する必要はありませんIStepViewModel
インターフェイスにプロパティを追加できると思っていましたが、各クラスで明示的に実装する必要があります。(だから、これは良くない)
インターフェイスでリフレクションを使用して実装できると考えていますが、インターフェイスのメソッドでインスタンスを参照することはできません。