在 ASP.NET MVC 中使用 ExpandoObject 时出错

Error using ExpandoObject in ASP.NET MVC

我有一个 ASP.NET MVC 应用程序。我在我的应用程序中使用 ExpandoObject。目前,我的 .cshtml 文件中有以下块:

foreach (System.Dynamic.ExpandoObject expo in ViewBag.ExpandoObjects)
{
  <div>@filter.GetType().FullName</div>
}  

这段代码工作正常。事实上,它会像我期望的那样在屏幕上打印出 System.Dynamic.ExpandoObject。但是,当我将代码更新为以下内容时,出现错误。

foreach (System.Dynamic.ExpandoObject expo in ViewBag.ExpandoObjects)
{
  foreach (var key in expo.Keys) 
  {
    <div>@key</div>
  }
}                  

错误说:

CS1061: 'System.Dynamic.ExpandoObject' does not contain a definition for 'Keys' and no extension method 'Keys' accepting a first argument of type 'System.Dynamic.ExpandoObject' could be found (are you missing a using directive or an assembly reference?)      

我不明白为什么会出现此错误。根据文档,有一个Keys property。我错过了什么?

Keys 属性 是为 IDictionary 接口明确实现的。例如,这不会编译:

Console.WriteLine(new ExpandoObject().Keys);

如果您想使用 Keys,您必须将其转换为 IDictionary

foreach (System.Dynamic.ExpandoObject expo in ViewBag.ExpandoObjects)
{
  foreach (var key in ((IDictionary<string, object>)expo).Keys) 
  {
    <div>@key</div>
  }
}  

如果您想通过编译时知道的名称访问键,您可以使用字典索引器或将对象转换为 dynamic.

foreach (IDictionary<string, object> expo in ViewBag.ExpandoObjects)
{
    <div>@expo["name"]</div>

foreach (dynamic expo in ViewBag.ExpandoObjects)
{
    <div>@expo.name</div>

这是一个简短的代码片段,让您了解如何将 ExpandoObject 转换为 ExpandoObjectdynamicIDictionary<string, object>:

var obj = new ExpandoObject();
var dict = ((IDictionary<string, object>)obj);
var dyn = (dynamic) obj;
dyn.name = "Fred";
Console.WriteLine(dyn.name);  // "Fred"
var key = dict.Keys.Single();
Console.WriteLine(key);       // "name"
Console.WriteLine(dict[key]); // "Fred"

请注意,我强烈建议您尽可能使用强类型视图模型。 dynamic 打字有利于它的用途,但如果过度使用会破坏可维护性。