бритва с классом модели анонимного типа. Это возможно? - PullRequest
19 голосов
/ 07 июля 2011

Я хочу создать представление, используя шаблон бритвы, но я не хочу писать класс для модели, потому что во многих представлениях у меня будет много запросов, которые будут возвращать разные модели.

Например, у меня есть запрос 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 */
};

Мне нужно написать View для этого запроса. Этот запрос возвращает статьи.

Теперь я не знаю, как должно выглядеть определение модели.

Я пытался использовать это определение:

@model System.Collections.IEnumerable

Но тогда у меня была ошибка, чем fileds, не существует в типе объекта:

* CS1061: «объект» не содержит определения для «поля_добавок», и невозможно найти метод расширения «поле_добавок», принимающий первый аргумент типа «объект» *

Это моя модель, для которой я не хочу писать следующую модель. Конечно

Ответы [ 4 ]

42 голосов
/ 07 июля 2011

Краткий ответ: использование анонимных типов не поддерживается , однако есть обходной путь , вы можете использовать ExpandoObject

Установите вашу модель на @model IEnumerable<dynamic>

Тогда в контроллере

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;
    }
}
1 голос
/ 01 мая 2019

Самое простое решение, если вы используете C # 7.0+ (представлен в Visual Studio 2017+), - это использовать кортеж, а не анонимный тип.

Razor View: "_MyTupledView.cshtml"

@model (int Id, string Message)

<p>Id: @Model.Id</p>
<p>Id: @Model.Message</p>

Затем, когда вы связываете это представление, вы просто отправляете кортеж:

var id = 123;
var message = "Tuples are great!";
return View("_MyTupledView", (id, message))
1 голос
/ 02 декабря 2015

Кажется, вы не можете передавать анонимные типы, но если вы просто хотите получить значения типа, вы можете передать для просмотра перечисляемый массив объектов.

Вид:

@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>

Контроллер:

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);
            }


        }

    }
1 голос
/ 21 декабря 2011

Я думаю, что это еще лучшее решение:

http://buildstarted.com/2010/11/09/razor-without-mvc-part-iii-support-for-nested-anonymous-types/

Это позволяет использовать вложенные анонимные типы, которые вышеупомянутое решение для расширенных объектов не будет обрабатывать.

...