扩展方法不适用于通过ViewBag传递的模型实例的属性

时间:2013-03-21 16:22:56

标签: asp.net-mvc extension-methods viewbag

我有以下字符串扩展方法:

public static string Truncate(this string value, int maxLength = 75)
{
    /* ... */
}

我想在视图中使用它,它适用于文字字符串。但是当我在ViewBag中有一个模型实例(让我们称之为object)并尝试Truncate其中一个字符串属性时,我得到一个RuntimeBinderException

  

“string”不包含“Truncate”

的定义

为什么会这样?我可以解决这个问题吗?

感谢。

2 个答案:

答案 0 :(得分:4)

由于ViewBagdynamic类型,因此在不首先转换为适当类型的情况下,不会在其属性中选择扩展方法。

例如:

@(((string)ViewBag.stringProperty).Trunctate())

我个人限制ViewBag的使用,以避免在任何地方施放(以及其他原因)。相反,我为每个视图使用强类型视图模型。


为了完整起见,如果您的视图中未引用包含扩展名的命名空间,也会遇到此错误。

您可以在位于views文件夹中的web.config中添加命名空间:

enter image description here

将命名空间添加到以下部分:

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="MyProject.Extensions" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

或者,您可以在剃刀视图中导入命名空间:

@using MyProject.Extensions

答案 1 :(得分:0)

我做的事情(干净)

@{
    string areaName = ViewBag.AreaName;
}

...然后 <h4>@areaName.ExtensionMethod()</h4>