Używanie MVC 3 z silnikiem widoku Razor. Mam ten widok:
@model dynamic
@{
var products = (List<ListItemBaseModel>)Model.Products;
var threshold = (int)(Model.Threshold ?? 1);
var id = Guid.NewGuid().ToString();
}
Jest wywoływana z innego widoku przy użyciu tego kodu:
@Html.Partial("PartialViewName", new { Products = Model, Threshold = 5 })
W obu widokach, kiedy debuguję je i oglądam Model, wydaje się, że zawiera on poprawny obiekt. Kiedy wykonuję kod, w wierszu „var products =” pojawia się błąd o treści:
„obiekt” nie zawiera definicji „produktów”
Czy ktoś może mi wyjaśnić, dlaczego otrzymuję ten błąd? Ponownie, kiedy oglądam obiekt Model w trybie debugowania, wygląda dobrze (ma 2 właściwości: produkty i próg)
asp.net-mvc-3
razor
Ruud van Falier
źródło
źródło
Odpowiedzi:
Czy jako model widoku przekazujesz wystąpienie klasy anonimowej? Właśnie wypróbowałem to (model widoku dynamicznego w CSHTML) i otrzymałem ten sam błąd, co twój, gdy używam klasy anonimowej, ale działało dobrze, gdy utworzyłem nazwaną klasę. Szukałem, ale nigdzie nie widziałem tego udokumentowanego.
EDYCJA # 1:
Według Davida Ebbo nie można przekazać typu anonimowego do widoku z typami dynamicznymi, ponieważ typy anonimowe są kompilowane jako
internal
. Ponieważ widok CSHTML jest kompilowany do oddzielnego zestawu, nie może uzyskać dostępu do właściwości typu anonimowego.EDYCJA # 2:
David Ebbo zredagował swój post z tym wyjaśnieniem:
źródło
return View(new { Foo = 1, Bar = "test" });
? Ponieważ używam MVC 4 i nadal otrzymuję komunikat „obiekt nie zawiera definicji dla Foo”ToExpando
jednego)Na .NET 4.0 typy anonimowe można łatwo przekonwertować na ExpandoObjects, a zatem wszystkie problemy są naprawiane z narzutem samej konwersji. Sprawdź tutaj
źródło
Nie ma to nic wspólnego z typami anonimowymi, które mają właściwości wewnętrzne
Jest całkowicie możliwe przekazanie anonimowych typów z widoku do częściowego widoku
Napotkałem dziś ten sam problem i nie miał on (bezpośrednio) nic wspólnego z problemem przekazywania anonimowych typów i ich nieodłącznych
internal
właściwości.W związku z tym, w odniesieniu do pytania PO, odpowiedź @Lucas jest nieistotna - mimo że obejście zadziała .
W pytaniu PO anonimowy typ jest przekazywany z widoku w zestawie X do częściowego w zestawie X , dlatego problem, który przedstawił David Ebbo, dotyczący właściwości wewnętrznych dla typów anonimowych, nie ma żadnego znaczenia; typy skompilowane dla widoku, typ częściowy i anonimowy są zawarte w tym samym zestawie .
Więc co powoduje nagłe niepowodzenie w przekazaniu anonimowego typu z widoku do częściowego?
Przynajmniej w mojej sytuacji odkryłem, że było to spowodowane innym widokiem w TYM SAMYM FOLDERZE, który określa typ modelu, którego nie można rozwiązać . Widoki są kompilowane w czasie wykonywania, więc miałoby to sens, ponieważ kompilacja widoków w czasie wykonywania oznaczałaby również niepowodzenie kompilacji typów dynamicznych, a częściowa po prostu otrzymałaby plik
object
. Nie jest od razu oczywiste, co się dzieje, ale w konkretnym przykładzie PO (i moim) jest to najprawdopodobniej przyczyną problemu.Warto zauważyć, że jeśli typ modelu jest poprawny, ale inna część widoku nie kompiluje się, to nie wpływa to w ten sam sposób na typy anonimowe. Musi to wynikać z tego, jak Razor rozbija dynamiczną kompilację części składowych widoku.
Po poprawieniu nieprawidłowego widoku odbuduj całe rozwiązanie lub wyczyść i odbuduj projekt przed sprawdzeniem, czy został naprawiony.
Aby upewnić się, że nie zostaniesz ponownie zaskoczony, możesz włączyć kompilację w czasie kompilacji widoków Razor, dodając to do swojego
csproj
pliku:źródło
Dodaj następującą klasę w dowolnym miejscu w swoim rozwiązaniu (użyj przestrzeni nazw System, aby była gotowa do użycia bez konieczności dodawania żadnych odwołań) -
Kiedy wysyłasz model do widoku, przekonwertuj go na Expando:
źródło
Zamiast używać
dynamic
typu Model w widoku częściowym.Możesz wywołać anonimowe atrybuty obiektu za pomocą
@ViewData.Eval("foo")
zamiast@Model.foo
.Następnie możesz usunąć
@Model dynamic
z widoku.Niedawno natknąłem się na ten problem podczas przekazywania niektórych atrybutów między widokami w celu integracji komentarzy społecznościowych na Facebooku. Przykładowy kod:
Wtedy moim zdaniem po prostu miałem ten div:
źródło
nie jestem pewien, czy otrzymujesz ten błąd, ponieważ nie wdrażasz obejścia. mam ten sam błąd w częściowym widoku. rozwiązaniem było po prostu wyczyszczenie kompilacji i odbudowanie jej. jeśli składnia jest poprawna, kod powinien działać, ale silnik maszynki do golenia może nie aktualizować poprawnie kodu.
źródło
Obejrzałem ten problem za pomocą słownika.
źródło
Aby użyć
dynamic
typu, musisz odwołać się doMicrosoft.CSharp
zestawuźródło