动态视图匿名类型缺失成员问题 - MVC3

2024-02-19

我有一个 MVC3 站点,我已经设置它来测试另一个站点 - 大部分站点都是快速而肮脏的,所以我没有去镇上为所有视图创建模型和视图模型类型 - 仅在需要输入的地方用户。

好的,我有一个控制器方法,可以投影 Linq 序列并将其设置为ViewBag.

ViewBag.SomeData = Enumerable.Range(1,10).Select(i=> new { Value = i });

在我看来(Razor C#),我想读一下这个 - 非常简单:

@foreach(dynamic item in ViewBag.SomeData)
{
  @:Number: @item.i
}

当然,除了我得到一个RuntimeBinderException因为在控制器中创建的匿名类型是 Web 项目的输出程序集的内部,并且此处的实际 Razor 代码将在构建管理器生成的不同程序集中运行,所以总而言之DENIED!

显然,“适当的”模型类型可以解决问题 - 但假设我根本不想这样做,因为这是我的特权(!) - 如何最好地将代码保持在最低限度并保留此处的动态性?


这就是我所做的(我强调这只能真正充分解决匿名类型的问题);将成员提出并推入ExpandoObject.

我最初的改变是使投影成为返回一个的多语句ExpandoObject:

ViewBag.SomeData = Enumerable.Range(1,10).Select(i=> {
  var toReturn = new ExpandoObject();
  toReturn.Value = i;
  return toReturn;
});

它几乎和匿名类型一样短,只是不那么干净。

但后来我想知道是否可以从匿名类型中获取公共可读的成员(类型是内部的,但它生成的属性是公共的):

public static class SO7429957
{
  public static dynamic ToSafeDynamic(this object obj)
  {
    //would be nice to restrict to anonymous types - but alas no.
    IDictionary<string, object> toReturn = new ExpandoObject();
  
    foreach (var prop in obj.GetType().GetProperties(
      BindingFlags.Public | BindingFlags.Instance)
      .Where(p => p.CanRead)) // watch out for types with indexers 
    {
      toReturn[prop.Name] = prop.GetValue(obj, null);
    }

    return toReturn;
  }
}

这意味着我可以使用我的原始代码 - 但在末尾标记了一些扩展方法调用:

ViewBag.SomeData=Enumerable.Range(1,10).Select(i=> new { Value = i }.ToSafeDynamic());

It's not高效,而且绝对应该not用于严肃的生产代码。但这是一个很好的节省时间的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态视图匿名类型缺失成员问题 - MVC3 的相关文章

随机推荐