2010-10-28 16 views
60

Kiedy próbuję uczynić częściowy widok, którego wzór jest określony jako typ:Render częściowy widok z dynamicznym modelu w widoku Razor silnika i ASP.NET MVC 3

@model dynamic 

za pomocą następującego kodu:

@{Html.RenderPartial("PartialView", Model.UserProfile);} 

otrzymuję następujący wyjątek:

'System.Web.Mvc.HtmlHelper<dynamic>' has no applicable method named 'RenderPartial' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax. 

jednak ten sam kod w pliku .aspx działa bez zarzutu. jakieś pomysły?

Odpowiedz

53

Po prostu znalazłem odpowiedź, wydaje się, że widok, w którym umieszczałem kod RenderPartial, miał model dynamiczny, a zatem MVC nie może wybrać prawidłowej metody użycia. Przesłanie modelu w wywołaniu RenderPartial do poprawnego typu rozwiązało problem.

źródło: Using Html.RenderPartial() in ascx files

+12

Prawo, główny powód to nie działa jest to, że C# nie obsługuje wywoływania metody rozszerzającej (czyli 'Html.RenderPartial()'), gdy którykolwiek z argumentów jest typu dynamicznego. Musisz albo wywołać metodę rozszerzenia statycznie, albo rzucić argument na typ niedynamiczny. – Eilon

16

Może być również nazywane jako

@Html.Partial("_PartialView", (ModelClass)View.Data) 
+0

Ma to wadę, że generuje tymczasowy (i potencjalnie duży) 'MvcHtmlString' w locie, a nie tylko bezpośrednio zapisuje dane wyjściowe. –

+0

Czy to nie działa z RenderPartial? – ajbeaven

+0

Znalazłem, że muszę rzucić mój model w ten sposób, mimo że mój model nie został zadeklarowany jako "dynamiczny". Prawdopodobnie dlatego, że mój model był listą. – levininja

25

Zamiast odlewania model w renderPartial wezwanie, a ponieważ używasz maszynki można zmodyfikować pierwszą linię w widoku z

@model dynamic 

do

@model YourNamespace.YourModelType 

Ma to tę zaletę, że działa na każdym wywołaniu @Html.Partial, a także zapewnia intellisense dla właściwości.

+5

+1 wydaje się bardziej sensowny niż sugestia Diego - z powodów wymienionych powyżej. np. jeśli wiesz, z jakim typem masz do czynienia, radzimy sobie z tym typem! – MemeDeveloper

+0

nie ma sensu. Jeśli chcę korzystać z modelu dynamicznego, chciałbym, aby pomocnicy mi pomogli. Model dynamiczny w większości przypadków jest prostszy i bardziej produktywny, ponieważ nie trzeba deklarować klas. – ema

+2

@ema - używanie modeli dynamicznych prowadzi również do niedbałego, źle przemyślanego kodu. ViewModels są prawie zawsze lepszym pomysłem niż modele dynamiczne. Chyba że lubisz znajdować błędy kompilacji podczas pracy! –

3

Oto sposób, aby zdać dynamiczny obiekt w widoku (lub częściowym widokiem)

Dodaj następujące klasy w dowolnym miejscu w rozwiązanie (nazw obsłudze system, więc jego gotowy do użycia bez konieczności dodawania jakichkolwiek odniesień) -

namespace System 
    { 
     public static class ExpandoHelper 
     { 
      public static ExpandoObject ToExpando(this object anonymousObject) 
      { 
       IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject); 
       IDictionary<string, object> expando = new ExpandoObject(); 
       foreach (var item in anonymousDictionary) 
        expando.Add(item); 
       return (ExpandoObject)expando; 
      } 

     } 
    } 

po wysłaniu modelu do widoku, konwertować je do EXPANDO:

return View(new {x=4, y=6}.ToExpando()); 

Cheers

7

Jest jeszcze jeden powód, dla którego można go rzucić, nawet jeśli nie używasz dynamicznego/ExpandoObject. Jeśli robisz pętlę, na przykład:

@foreach (var folder in ViewBag.RootFolder.ChildFolders.ToList()) 
{ 
    @Html.Partial("ContentFolderTreeViewItems", folder) 
} 

w tym przypadku „var” zamiast deklaracja typu rzuci ten sam błąd, pomimo faktu, że RootFolder jest typu „Folder zmieniając. var do rzeczywistego typu, problem znika.

@foreach (ContentFolder folder in ViewBag.RootFolder.ChildFolders.ToList()) 
{ 
    @Html.Partial("ContentFolderTreeViewItems", folder) 
} 
0

miałem ten sam problem & w moim przypadku jest to, co zrobiłem

@Html.Partial("~/Views/Cabinets/_List.cshtml", (List<Shop>)ViewBag.cabinets) 

i częściowym widokiem

@foreach (Shop cabinet in Model) 
{ 
    //... 
} 
Powiązane problemy