Search code examples
asp.net-mvcextension-methodsviewbag

Extension methods don't work on properties of a model instance passed via ViewBag


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.


Solution

  • 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:

    enter image description here

    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