2011-07-07 14 views
18

Chcę utworzyć widok za pomocą szablonu maszynki do golenia, ale nie chcę pisać klasy dla modelu, ponieważ w wielu widokach będę miał wiele zapytań, które będą zwracać różne modele.widok maszynki z klasą modelu typu anonimowego. To jest możliwe?

Na przykład mam kwerendy LINQ:

from p in db.Articles.Where(p => p.user_id == 2) 
select new 
{ 
    p.article_id, 
    p.title, 
    p.date, 
    p.category, 
    /* Additional parameters which arent in Article model */ 
}; 

muszę napisać dla tego zapytania. To zapytanie zwraca artykuł.

Teraz nie wiem, jak powinna wyglądać definicja modelu.

Próbowałem użyć tego deffinition:

@model System.Collections.IEnumerable 

Ale wtedy miałem erros niż fileds robi istnieje w rodzaju obiektu:

* CS1061: 'obiekt' nie zawierają definicji dla „addition_field "i bez metody rozszerzenia" add_field "można znaleźć pierwszy argument typu" obiekt "*

To jest mój model, dla którego nie chcę pisać następnego modelu. Oczywiście

+0

'@model System.Collections.IEnumerable

' –

+0

tego zapytania wydaje się Projekcja 'IEnumerable' anonimowych typów, a nie' Article' –

+0

Czy możesz wyjaśnić, dlaczego nie chcesz pisać modelu? Istnieją zalety korzystania z klas modeli - np. możesz użyć intellisense, możesz w większym stopniu korzystać z klas częściowych i dodawać atrybuty takie jak sprawdzanie poprawności do klas modeli. – Stuart

Odpowiedz

39

Krótka odpowiedź jest taka, że ​​using anonymous types is not supported jednak there is a workaround, można użyć ExpandoObject

Ustaw swój model @model IEnumerable<dynamic>

Następnie w sterowniku

from p in db.Articles.Where(p => p.user_id == 2) 
select new 
{ 
    p.article_id, 
    p.title, 
    p.date, 
    p.category, 
    /* Additional parameters which arent in Article model */ 
}.ToExpando(); 

... 
public static class Extensions 
{ 
    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; 
    } 
} 
+0

wielkie dzięki :) – nosbor

+0

+1 Chciałbym móc to zrobić więcej niż raz. 'ToExpando' to świetny pomysł! –

1

Wygląda na to, że nie można przekazywać typów anonimowych, ale jeśli chcemy tylko wartości typu, które można przekazać do wyliczenia tablicy obiektów do wyświetlenia.

Widok:

@model IEnumerable<object[]> 

@{ 
    ViewBag.Title = "Home Page"; 
} 

<div> 
    <table> 
     @foreach (var item in Model) 
     { 
      <tr> 
       <td>@item[0].ToString()</td> 
       <td>@item[1].ToString()</td> 
      </tr> 
     } 
    </table> 
</div> 

Kontroler:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 

    namespace ZZZZZ 
    { 
     public class HomeController : Controller 
     { 
      public ActionResult Index() 
      { 

       List<object[]> list = new List<object[]> { new object[] { "test1", DateTime.Now, -12.3 } }; 

       return View(list); 
      } 


     } 

    } 
+0

Całkiem nieźle :-) – netfed

Powiązane problemy