I have the following string extension method:
public static string Truncate(this string value, int maxLength = 75)
{
/* ... */
}
I want to use it in views, and it works properly with literal strings. But when I have a model instance (let's call it object
) in ViewBag and try to Truncate
one of its string properties, I get a RuntimeBinderException
:
"string" does not contain a definition for "Truncate"
Why does it happen? Can I fix that?
Thanks.
Because the ViewBag
is a dynamic
type, extension methods will not be picked up on their properties without casting to the appropriate type first.
For example:
@(((string)ViewBag.stringProperty).Trunctate())
Personally I limit my usage of ViewBag
to avoid having to cast everywhere (amongst other reasons). Instead I use strongly typed view models for each view.
For sake of completeness, this error could also be encountered if the namespace that contains your extension is not referenced in your view.
You can add the namespace in the web.config that sits in your views folder:
Add namespace to the following section:
<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>
Alternatively, you can import the namespace in the razor view itself:
@using MyProject.Extensions