带有匿名类型模型类的Razor视图.这是可能的

本文关键字:视图 Razor 类型 模型 | 更新日期: 2023-09-27 18:01:23

我想使用razor模板创建一个视图,但我不想为模型编写一个类,因为在许多视图中,我将有许多查询,这将返回不同的模型。

例如,我有一个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 */
};

我需要为这个查询写一个视图。这个查询返回一个Articles。

现在我不知道应该如何看起来像一个模型定义。

我尝试使用这个定义:

@model System.Collections.IEnumerable

但是我有一个错误比字段不存在的对象类型:

*CS1061: 'object'不包含'addition_field'的定义,并且无法找到接受'object'类型的第一个参数的'addition_field'扩展方法*

这是我的模型,我不想为它写下一个模型。当然

带有匿名类型模型类的Razor视图.这是可能的

简短的回答是不支持使用匿名类型,但是,有一个解决方法,您可以使用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;
    }
}

如果你正在使用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))

我认为这是一个更好的解决方案:

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

这允许嵌套的匿名类型,前面提到的expando-object解决方案无法处理。

似乎你不能传递匿名类型,但如果你只是想要类型的值,你可能会传递一个对象数组的可枚举对象来查看。

视图:

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

        }
    }