ASP.NET MVC V2-デバッグモデルのバインディングの問題 - バグ?
-
16-09-2019 - |
質問
私は、私が持っている特定のケースでMVCが正しく拘束されない理由をデバッグしようとして少し困難を抱えています...
基本的に、複雑なオブジェクトを受信するアクションがあり、複雑な子オブジェクト-Activity.Location.State(アクティビティが期待される複雑なオブジェクトであり、場所は複雑な子オブジェクトであり、状態は単なる文字列です) 。
今、私はテストプロジェクトを設定しました。これは、私が持っている実際のシナリオを正確に模倣することができる限り、このテストのケースではバインディングが機能します...しかし、私の実際のプロジェクトでは、アクティビティへのバインディングは機能しますが、位置ではありません... Locaitonプロパティ内にブレークポイントを置くことで、MVCがアクティビティから複雑な位置オブジェクトを取得しているが、プロパティのいずれも設定していないことがわかります...
私は問題をデバッグしようとしていますが、追跡できないように見えるMVC V2プレビュー2シンボルにアクセスする必要があります...場所オブジェクトを引き出したら実際に何をしているのかを見たいです(一部の人のために理由は、内部で失敗しているかもしれないが、例外を飲み込んでいると思う。
ここで私ができることについてのアイデア...
乾杯アンソニー
アップデート:
わかりました、私はJWが提案したことをし、MVCプロジェクトを直接参照しました...
私は問題を発見しましたが、私が見落としていた非常に小さな違いが1つありました...結果として、MVCはモデルバインディングに関しては現在複数のレベルのインターフェイス継承をサポートしていないことがわかりました...以下を参照してください...
//MODEL
public class Location : ILocation
{
...
}
public interface ILocation : ILocationCore
{
...
}
public interface ILocationCore //In my sample I didn't have this second level interface
{
...
//MVC doesn't find any of these properties
...
}
public class Activity : IActivity
{
...
}
public interface IActivity : IActivityCore
{
ILocation Location { get; set; } //MVC finds this and reads its meta type as an ILocation
//Also the implementation of this Location within Activity will always return a instance - our IoC takes care of that, so MVC should never have to create the instance
}
public interface IActivityCore
{
...
}
//CONTROLLER
public ActionResult Create(Activity activity)
{
}
したがって、私が見つけたのは、MVCが場所を見つけてメタタイプをilocationとして読み取ることですが、getModelPropertiesがdefaultModelbinder内で実行されると、次のものが発生します -
protected virtual PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
return GetTypeDescriptor(controllerContext, bindingContext).GetProperties();
//This return no properties
}
protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) {
return new AssociatedMetadataTypeTypeDescriptionProvider(bindingContext.ModelType).GetTypeDescriptor(bindingContext.ModelType);
//bindingContext.ModelType - is ILocation
}
したがって、私はこの時点で、TypedScriptionProviderがこのスタイルの継承をサポートしていないと仮定していますが、これは非常に驚いています。また、V1ソースを見ると、これはV2で導入されたように見えますが、V1はとにかく私がやろうとしていることをサポートできなかったかもしれません。
これは本当にバグだとは言いませんが、インターフェイスをコンクリートクラスに交換してみましたが、うまくいきました。したがって、行動は私が期待するものではなく、少し矛盾しています。
何かご意見は???この継承はかなり標準ではないと思っていましたが、ケータリングするのに十分頻繁に発生するでしょう。返信いただきありがとうございます。
乾杯
解決
この動作は、インターフェイスの継承の仕組みにより、設計によるものです。インターフェイスは実装を定義していないため、iLocationはiLocationSourceの特性を「継承」しません。むしろ、iLocationは、具体的な実装が実装しなければならないもののみを定義します。
この動作を定義するCLI(共通言語インフラストラクチャ)仕様のセクションを含む詳細については、以下をご覧ください。 http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx
他のヒント
CodePlexで公開されたASP.NET MVC2ソースコードを単に参照します。私はそれをしました、それは非常に簡単です。
ソースコードを介してデバッグする際に、はるかによく理解できます。