21

我在尝试调试为什么 MVC 在给定情况下无法正确绑定时遇到了很多困难...

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

现在我建立了一个测试项目,据我所知,它完全模仿了我所拥有的实际场景,在这个测试用例中,绑定有效……但在我的实际项目中,绑定到 Activity 有效,但不绑定到 Location……通过在 Locaiton 属性中放置断点,我可以看出 MVC 正在从 Activity 中检索复杂的 Location 对象,但它没有设置任何属性......

我正在尝试调试该问题,但我需要访问我似乎无法追踪的 MVC v2 preview 2 符号......我想看看它在拉出位置对象后实际在做什么(对于某些原因我认为它可能会在内部失败但会吞下异常)。

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

干杯安东尼

更新:

好的,我按照 JW 的建议做了,直接引用了 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,但是当 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
    }

因此,我现在假设 TypeDescriptionProvider 不支持这种继承方式,对此我感到非常惊讶。还查看 v1 源代码,它看起来像是 v2 引入的 - 但 v1 可能无法支持我正在尝试做的事情。

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

有什么想法吗???我会认为这种继承不是相当标准,但会经常发生,足以满足要求。谢谢回复。

干杯

4

2 回答 2

45

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

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

于 2009-11-04T22:28:46.393 回答
3

我将简单地参考在 codeplex 中发布的 asp.net mvc2 源代码。我做到了,这很简单。

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

于 2009-11-04T21:41:39.517 回答