我可以传递一个匿名types到我的ASP.NET MVC视图吗?

我刚开始使用ASP.NET MVC,现在处于testing阶段。 在我的代码中,我正在运行一个简单的LINQ to SQL查询来获取结果列表并将其传递给我的视图。 这样的事情:

var ords = from o in db.Orders where o.OrderDate == DateTime.Today select o; return View(ords); 

然而,在我看来,我意识到我需要访问每个订单的客户名称。 我开始使用o.Customer.Name但我相当肯定,这是执行一个单独的查询每个订单(因为LINQ的懒加载)。

减less查询次数的逻辑方法是同时select客户名称。 就像是:

 var ords = from o in db.Orders from c in db.Customers where o.OrderDate == DateTime.Today and o.CustomerID == c.CustomerID select new { o.OrderID, /* ... */, c.CustomerName }; return View(ords); 

除了现在我的“ords”variables是一个匿名types的IEnumerable。

是否有可能声明一个ASP.NET MVC视图的方式,它接受一个I​​Enumerable作为其视图数据,其中T由控制器传递什么定义,或者我将不得不定义一个具体的types来填充我的查询?

你能把它传递给视图吗? 是的,但是您的观点不会被强制input。 但佣工会工作。 例如:

 public ActionResult Foo() { return View(new {Something="Hey, it worked!"}); } //Using a normal ViewPage <%= Html.TextBox("Something") %> 

该文本框应呈现“嘿,它的工作!” 作为价值。

那么你可以定义一个视图,其中T是由从控制器传递给它的东西来定义的。 那么是的,但显然不是在编译时。

想一想。 当你为一个视图声明一个模型types的时候,这样你就可以获得视图的智能感知。 这意味着types必须在编译时确定。 但问题是,我们可以在运行时从给定的东西中确定types。 当然,但不能保持强大的打字。

你怎么会得到一个你不知道的types的Intellisense? 在运行时,控制器最终可以传递任何types的视图。 我们甚至无法分析代码和猜测,因为动作filter可能会更改传递给视图的对象。

我希望澄清答案,而不是更加混淆。 🙂

可以将匿名types传递给视图,只要记住将模型转换为dynamic。

你可以这样做:

 return View(new { MyItem = "Hello", SomethingElse = 42, Third = new MyClass(42, "Yes") }) 

在视图的顶部,你可以做到这一点(在这里使用剃刀)

 @{ string myItem = (dynamic)Model.MyItem; int somethingElse = (dynamic)Model.SomethingElse; MyClass third = (dynamic)Model.Third; } 

或者你可以像ViewData一样从ViewData转换它们:

 @{ var myItem = ViewData.Eval("MyItem") as string var somethingElse = ViewData.Eval("SomethingElse") as int? var third = ViewData.Eval("Third") as MyClass } 

在.NET 4.0中,匿名types可以很容易地转换为ExpandoObjects,因此所有的问题都可以通过转换本身的开销来解决。 看看这里

今天晚上我发现了DataLoadOptions类和它的LoadWith方法。 我能够告诉我的LINQ to SQL DataContext总是加载一个Customers行,每当订单行被检索,所以原来的查询现在得到我需要的一切。

这里是一篇关于将匿名types传递给视图并绑定数据的文章。

谢谢

这篇文章展示了如何从一个方法中返回一个匿名types,但是这不符合你的需求。

另一种select可能是将匿名types转换为JSON(JavaScriptSerializer将执行此操作),然后将该JSON返回给视图,然后您需要一些jQuery等来执行您喜欢的操作。

我一直在使用Linq将我的数据“塑造”成JSON格式,我的观点需要非常成功。

您可以编写一个具有您的匿名types的相同属性的类,并且可以将您的匿名types转换为您的手写types。 缺点是当你在你的linq查询中进行投影更改时,你必须更新这个类。

您可能能够传递一个对象并使用reflection来获得您想要的结果。 查看一下ObjectDumper.cs(包含在csharpexamples.zip中)。

如果我没有弄错,匿名types在编译时转换为强types对象。 不pipe强types对象是否对视图数据有效,都是另一个问题。

我遇到了同样的问题…在思考了一下之后,我得出结论:最正确和最可扩展的解决scheme是在发送给View之前,将这个匿名types序列化。 因此,您可以使用相同的方法来使用后面的View代码填充页面,并使用JSON来填充页面