2009-11-04 21 views
21

Mam więcej niż niewielką trudność próbując debugować, dlaczego MVC nie jest prawidłowa w danym przypadku Mam ...ASP.net MVC v2 - Debugowanie problemów wiązania modelu - BŁĄD?

Zasadniczo mam swoje działanie, które otrzymuje złożony obiekt, który z kolei ma złożone dziecko object - Activity.Location.State (gdzie Activity jest złożonym obiektem, którego oczekuje działanie, Location jest złożonym obiektem potomnym, a State jest tylko ciągiem znaków).

Teraz mam projekt testowy, który na tyle, na ile mogę dokładnie naśladować faktyczny scenariusz, który mam, w tym przypadku testowym wiąże się ... Ale w moim rzeczywistym projekcie, powiązanie z Aktywnością działa, ale nie Lokalizacja ... Umieszczając punkty przerwania w obrębie właściwości Locaiton, mogę stwierdzić, że MVC pobiera złożony obiekt lokalizacji z działania, ale nie ustawia żadnej z właściwości ...

Próbuję usunąć błąd, ale Potrzebuję dostępu do symboli podglądu 2 MVC v2, których nie mogę wyśledzić ... Chciałbym zobaczyć, co faktycznie robi, gdy wyciągnie obiekt lokalizacji (z jakiegoś powodu myślę, że może to zawodzić wewnętrznie ale przełknięcie wyjątku).

Wszelkie pomysły na to, co mogłem zrobić tutaj ...

Cheers Anthony

UPDATE:

Ok zrobiłem co J.W. zasugerował i bezpośrednio odwołał się do projektu MVC ...

Znalazłem problem i była jedna bardzo mała różnica, którą przeoczyłem ... W rezultacie odkryłem, że MVC obecnie nie obsługuje wielu poziomów dziedziczenia INTERFACE, gdy jest przychodzi do modelu wiązania ... Zobacz następujących ...

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

Stąd co znalazłem to, że MVC znajdzie lokalizację i odczytuje jego meta typu jako ILocation, ale kiedy GetModelProperties prowadzony jest w następujących DefaultModelBinder występuje -

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 
    } 

W związku z tym zakładam, że TypeDescriptionProvider nie obsługuje tego stylu dziedziczenia, który jestem dość zaskoczony przez. Również patrząc na źródło v1 wygląda na to, że wprowadzono to za pomocą v2 - ale v1 może nie obsługiwać tego, co i tak próbuję zrobić.

Nie powiedziałbym, że to naprawdę błąd, ale próbowałem zastąpić moje interfejsy konkretnymi klasami i działało dobrze. Dlatego zachowanie to nie jest tak naprawdę, czego bym się spodziewał i jest trochę niekonsekwentne.

Jakieś myśli ??? Pomyślałbym, że to dziedzictwo nie było dość standardowe, ale występowałoby wystarczająco często, by je zaspokoić. Dziękuję za odpowiedź.

Cheers

+0

Interfejsy nie mogą dziedziczyć tylko klasy mogą. Interfejsy określają wymagania implementacyjne. Jeśli powiesz: IFoo: IBar, mówisz kompilatorowi: "Każda klasa implementująca interfejs IFoo musi również implementować interfejs IBar". – ScottKoon

Odpowiedz

45

Okazuje się, że to zachowanie jest zgodne z projektem, ponieważ działa dziedziczenie interfejsu. Interfejsy nie definiują implementacji, a zatem lokalizacja nie "dziedziczy" właściwości ILocationSource.Zamiast tego, ilocation określa tylko to, co musi implementować konkretna implementacja.

do pełnej informacji w tym odcinku CLI (Common Language Infrastructure) Spec która określa ten problem, sprawdź: http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx

+0

Myślę, że komentarz Brada Wilsona jest taki, że zawsze pamiętam różnicę i oczekuję odpowiedniego zachowania. "Can Do vs Is A" –

+0

Tak - w rzeczywistości .NET zawsze brakowało wielu dziedziczenie - ku frustracji wielu programistów C++ przychodzących na platformę. Czy mogę polecić uzyskanie pełnego przeglądu Object Oriented Design, a następnie przeczytanie dobrej książki na C#. Oryginalny plakat wyraźnie próbuje uciec, zanim będzie mógł chodzić, rozwijając się na MVC, zanim w pełni zrozumie C#. Mówię, że to pomyłka i doprowadzi do wielu frustracji. – csharpforevermore

3

Chciałbym po prostu odwołać się do kodu źródłowego asp.net mvc2 opublikowanym w CodePlex. Zrobiłem to, to jest bardzo proste.

Zapewni to znacznie lepsze zrozumienie podczas debugowania kodu źródłowego.

Powiązane problemy