2009-11-04 7 views
21

Estoy teniendo más que un poco de dificultad tratando de solucionar por qué MVC no está vinculando correctamente en un caso dado Tengo ...ASP.net MVC v2 - Problemas de encuadernación del modelo de depuración - ¿ERROR?

Básicamente, tengo mi acción que recibe un objeto complejo que a su vez tiene un niño complejo object - Activity.Location.State (Donde Activity es el objeto complejo que espera la acción, Location es un objeto secundario complejo y State es solo una cadena).

Ahora configuro un proyecto de prueba que, por lo que puedo decir, imita exactamente el escenario real que tengo, en este caso de prueba, el enlace funciona ... Pero en mi proyecto real, el enlace a Activity funciona pero no Ubicación ... Al poner puntos de ruptura dentro de la propiedad de Locaiton puedo decir que MVC está recuperando el complejo objeto de ubicación de la actividad, pero no está configurando ninguna de las propiedades ...

Estoy tratando de solucionar el problema, pero Necesito acceder a los símbolos de la vista previa 2 de MVC que parece que no puedo rastrear ... Me gustaría ver lo que está haciendo realmente una vez que extrae el objeto de ubicación (por alguna razón, creo que podría estar fallando internamente) pero tragando la excepción).

¿Alguna idea sobre lo que podría hacer aquí ...

Saludos Anthony

ACTUALIZACIÓN:

autorización I lo hicieron J. W. sugirió y hace referencia directamente al proyecto MVC ...

Encontré el problema y hubo una pequeña diferencia que pasé por alto ... Como resultado, descubrí que MVC actualmente no admite múltiples niveles de herencia INTERFACE cuando viene a modelo de unión ... Ver la siguiente ...

//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) 
{ 
} 

Por lo tanto lo que he encontrado es que MVC encuentra la ubicación y lee su tipo meta como un ILocation, pero cuando GetModelProperties se ejecutan dentro del DefaultModelBinder la siguiente ocurre -

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 
    } 

Por lo tanto, supongo que en este punto TypeDescriptionProvider no es compatible con este estilo de herencia, lo cual me sorprende bastante. También mirando a la fuente v1 parece que esto fue presentado con v2 - pero v1 podría no haber sido capaz de soportar lo que estoy tratando de hacer de todos modos.

No diría que esto es realmente un error, pero traté de reemplazar mis interfaces con clases concretas y funcionó bien. Por lo tanto, el comportamiento no es realmente lo que esperaría y es un poco inconsistente.

¿Alguna idea? Hubiera pensado que esta herencia no era bastante estándar, pero ocurriría con la suficiente frecuencia como para atenderla. Gracias por la respuesta.

Saludos

+0

interfaces no pueden heredar, sólo las clases pueden. Las interfaces especifican los requisitos de implementación. Si dice IFoo: IBar, le está diciendo al compilador que "cualquier clase que implemente la interfaz IFoo también debe implementar la interfaz IBar". – ScottKoon

Respuesta

45

Resulta que este comportamiento es por diseño debido a cómo funciona la herencia de la interfaz. Las interfaces no definen implementaciones, por lo que ILocation no "hereda" las propiedades de ILocationSource.Más bien, ILocation solo define qué debe implementar una implementación concreta.

Para los detalles completos, incluyendo la sección de la CLI (Common Language Infrastructure) spec que define este comportamiento, echa un vistazo a: http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx

+0

Creo que el comentario de Brad Wilson es cómo siempre recuerdo la diferencia y espero el comportamiento apropiado. "Can Do vs Is A" –

+0

Sí, de hecho, .NET siempre ha carecido de herencia múltiple, para gran frustración de muchos desarrolladores de C++ que llegan a la plataforma. Puedo recomendar una visión general completa del Diseño orientado a objetos y luego leer un buen libro sobre C#. El cartel original claramente intenta correr antes de que puedan caminar, desarrollándose en MVC antes de que comprendan completamente C#. Digo que esto es un error y me llevará a mucha frustración. – csharpforevermore

3

yo simplemente hacer referencia al código fuente asp.net MVC2 publicado en CodePlex. Lo hice, es muy sencillo.

Le dará una mejor comprensión al depurar el código fuente.

Cuestiones relacionadas