ASP.net MVC v2 - 调试模型绑定问题 - BUG?

时间:2009-11-04 21:27:12

标签: asp.net asp.net-mvc asp.net-mvc-2 modelbinders

我在尝试调试为什么MVC在给定的情况下没有正确绑定时遇到了一点困难...

基本上,我的动作接收到一个复杂的对象,而该对象又有一个复杂的子对象 - Activity.Location.State(其中Activity是动作所期望的复杂对象,Location是一个复杂的子对象,State只是一个字符串)。

现在我设置了一个测试项目,据我所知,我确切地模仿了我的实际场景,在这个测试用例中绑定工作...但在我的实际项目中,绑定到Activity工作但不是位置...通过在Locaiton属性中放置断点,我可以告诉MVC正在从Activity中检索复杂的Location对象,但它没有设置任何属性......

我正在尝试调试这个问题,但是我需要访问MVC v2预览2符号,这些符号似乎无法跟踪...我希望看到一旦它拉出位置对象它实际上在做什么(出于某种原因,我认为它可能在内部失败但吞下了异常)。

关于我在这里可以做什么的任何想法......

干杯 安东尼

更新:

好的,我做了J.W.建议并直接参考MVC项目...

我发现了这个问题并且我忽略了一个非常小的区别......正如我的结果我发现当涉及到模型绑定时,MVC当前不支持多层INTERFACE继承...请参阅以下内容。 ..

//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找到了Location并将其元类型作为ILocation读取,但是当在DefaultModelBinder中运行GetModelProperties时会发生以下情况 -

    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
    }

因此我假设此时TypeDescriptionProvider不支持这种继承方式,我对此感到非常惊讶。另外看一下v1源代码,看起来这是v2引入的 - 但是v1可能无法支持我想要做的事情。

我不会说这确实是一个错误,但我尝试用具体的类替换我的接口,它工作正常。因此,这种行为并不是我所期望的,并且有点不一致。

有什么想法???我原本以为这种继承不是很标准,但经常会出现这种情况。谢谢你的回复。

干杯

2 个答案:

答案 0 :(得分:45)

由于接口继承的工作原理,这种行为是设计的。接口不定义实现,因此ILocation不会“继承”ILocationSource的属性。相反,ILocation仅定义具体实现必须实现的内容。

有关定义此行为的CLI(公共语言基础结构)规范部分的完整详细信息,请查看:http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx

答案 1 :(得分:3)

我只想参考codeplex中发布的asp.net mvc2源代码。我做到了,这非常简单。

通过源代码进行调试时,它可以让您更好地理解。