razor view with anonymous type model class. It is possible?
Solution 1:
The short answer is that using anonymous types is not supported, however, there is a workaround, you can use an ExpandoObject
Set your model to
@model IEnumerable<dynamic>
Then in the controller
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;
}
}
Solution 2:
The simplest solution if you are using C# 7.0+ (introduced in Visual Studio 2017+) is to use a tuple rather than an anonymous type.
Razor View: "_MyTupledView.cshtml"
@model (int Id, string Message)
<p>Id: @Model.Id</p>
<p>Id: @Model.Message</p>
Then when you bind this view, you just send a tuple:
var id = 123;
var message = "Tuples are great!";
return View("_MyTupledView", (id, message))
Solution 3:
I think this is an even better solution:
http://buildstarted.com/2010/11/09/razor-without-mvc-part-iii-support-for-nested-anonymous-types/
This allows for nested anonymous types, which the aforementioned expando-object solution won't handle.
Solution 4:
It seems you can't pass anonymous types but if you just want the values of the type you might pass an enumerable of an object array to view.
View:
@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>
Controller:
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);
}
}
}