【问题标题】:razor view with anonymous type model class. It is possible?具有匿名类型模型类的剃刀视图。有可能的?
【发布时间】:2011-09-30 13:46:32
【问题描述】:

我想使用 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 */
};

我需要为此查询编写一个视图。此查询返回文章。

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

我尝试使用这个定义:

@model System.Collections.IEnumerable

然后我有一个错误,对象类型中不存在文件:

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

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

【问题讨论】:

  • @model System.Collections.IEnumerable<Article>
  • 该查询似乎投射了匿名类型的 IEnumerable,而不是 Article
  • 你能解释一下为什么你不想写一个模型吗?使用模型类有很多优点——例如您可以使用智能感知,您可以更多地使用部分类,并且可以为模型类添加诸如验证之类的属性。
  • 这篇文章几乎是stackoverflow.com/questions/3758612/…的复制品,给你一个答案:这不可能。您需要遍历匿名枚举并将它们转换为动态对象
  • @Stuart - 我个人不使用模型类的原因是,在几乎所有情况下,它们都不是必需的,尤其是对于仅查看页面。没有它们让我可以非常轻松地调整和使用代码,而不是重新编写模型类,拥有所有额外的文件,以及维护不需要的东西通常令人头疼的事情。现在,如果 VS.Net(或 resharper/refactorpro)让他们的工作变得超级透明,我会考虑的。我发现的最好的方法是删除模型类,并使用 R!根据 Linq 查询重新生成它。

标签: c# asp.net-mvc asp.net-mvc-3 razor anonymous-types


【解决方案1】:

简短的回答是using anonymous types is not supported,但是there is a workaround,您可以使用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 我希望我能多次对此表示赞同。 ToExpando 是个好主意!
【解决方案2】:

如果您使用 C# 7.0+(在 Visual Studio 2017+ 中引入),最简单的解决方案是使用元组而不是匿名类型。

Razor 视图:“_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))

【讨论】:

    【解决方案3】:

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

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

    这允许嵌套匿名类型,上述扩展对象解决方案无法处理。

    【讨论】:

      【解决方案4】:

      您似乎无法传递匿名类型,但如果您只想要该类型的值,您可以传递对象数组的可枚举来查看。

      查看:

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

      【讨论】:

      • 还不错:-)
      猜你喜欢
      • 2015-02-17
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多