Вид бритвы с классом модели анонимного типа. Возможно?
Я хочу создать представление с использованием шаблона бритвы, но я не хочу писать класс для модели, потому что во многих представлениях у меня будет много запросов, которые будут возвращать разные модели.
Например, у меня есть запрос 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 */
};
Мне нужно написать представление для этого запроса. Этот запрос возвращает статьи.
Теперь я не знаю, как должно выглядеть определение модели.
Я попытался использовать это дефинитирование:
@model System.Collections.IEnumerable
Но тогда у меня был erros, чем fileds не существует в типе объекта:
* CS1061: 'object' не содержит определения для 'addition_field', и не может быть найден метод расширения 'addition_field', принимающий первый аргумент типа 'object' *
Это моя модель, для которой я не хочу писать следующую модель. Конечно,
Ответы
Ответ 1
Короткий ответ: использование анонимных типов не поддерживается, однако существует обходной путь, вы можете использовать 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;
}
}
Ответ 2
Я думаю, что это еще лучшее решение:
http://buildstarted.com/2010/11/09/razor-without-mvc-part-iii-support-for-nested-anonymous-types/
Это позволяет использовать вложенные анонимные типы, к которым не относится вышеупомянутое решение expando-object.
Ответ 3
Кажется, вы не можете передавать анонимные типы, но если вам просто нужны значения типа, вы можете передать перечислимый массив объектов для просмотра.
Вид:
@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);
}
}
}
Ответ 4
Самое простое решение, если вы используете С# 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))