Why You Can't Use Extension Methods With A WebGrid

5 (9 votes)

An interesting question came up recently on the ASP.NET forums. In it, the questioner was attempting to use my Chop() extension method to limit the number of characters in a WebGrid column but it wouldn't work. At first, I was a little stumped, so I tried it myself and got an error message:

'string' does not contain a definition for 'Chop'


Huh? The code looked fine:

            columnName : "Description",
            format: @<text>@item.Description.Chop(20)</text>

..and the extension method was placed in a class called Extensions within App_Code, so it should have worked, surely? Then I studied the error message a little more closely, and saw this:

Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'string' does not contain a definition for 'Chop'

The exception was being thrown by the RuntimeBinder, not the Compiler.

The argument that the WebGridColumn's Format parameter takes is a delegate: Func<dynamic,object>. What this means is that you have to pass in a dynamic type, and then something is done to it before it is returned as an object. A dynamic expression is resolved at runtime. The compiler doesn't know what it is.

When you try to use an extension method, the Compiler will check the type you are trying to use it on to see if such a method exists. If it doesn't. it will check any base classes that the type derives from to see if they contain a formal method with the right name. If that test fails, the Compiler will busy itself looking at any referenced static class which contains a static method with a first argument (the this part of an extension method) of the same type that the method is invoked on. In the case of the Chop method, that would a string. With dynamic variables, that reference isn't passed as part of the "Payload" to the RuntimeBinder, so it cannot find the extension method in your App_Code folder. And that, in the shell of a nut, is why you cannot use extension methods on a dynamic.

Great, so what can you do? Well, the extension method is still a static method on a class, so you can call it like this:

            columnName : "Description",
            format: @<text>@Extensions.Chop(item.Description, 20)</text>

Note that this issue doesn't just affect items from a query which are passed to the format method in a WebGrid - it affects all the results you get from a database query because the Database.Query method returns an IEnumerable<dynamic>. That means that you cannot simply apply an extension method in this context either:

@foreach(var item in data){
    @item.Description.Chop(30)<br />

One thing you can do in the above example (outside of a WebGrid) is to convert the dynamic return to a strongly typed one. You can use Jeremy Skinners Strongly Type helper for WebMatrix.Data for this (http://www.jeremyskinner.co.uk/2011/01/24/strongly-typed-data-access-with-webmatrix-data/).

If you have problems trying to use extension methods within the WebGridColumn's format argument, or anywhere else on the dynamic return from a method, hopefully you know what to do now. But this example also goes to show that it pays to read exception messages carefully.


Date Posted:
Last Updated:
Posted by:
Total Views to date: 11708


- Alistair

Hi Mike, after hitting my head with Use Extension Methods With A WebGrid, i found this article, i tried your suggestion but i keep getting the error below, any ideas?

CS1738: Named argument specifications must appear after all fixed arguments have been specified

- Amir

Thanks mate!

Recent Comments

raphael 27/11/2015 13:59
In response to ASP.NET 5: Managing Client-side Dependencies with NPM, Bower and Gulp
i fixed it. i'm not sure *what* it is that VS does, but you get the same result if you do a "npm on...

Raphael 27/11/2015 13:02
In response to ASP.NET 5: Managing Client-side Dependencies with NPM, Bower and Gulp
There seems to be a major issue with the dependency manager in VS2015. I haven't yet figured out but...

Joaquín Bresan 26/11/2015 17:58
In response to Getting the identity of the most recently added record
Great contribution friend. Thank you so much for sharing....

sumalatha 24/11/2015 22:09
In response to ASP.NET 5 Middleware, Or Where Has My HttpModule Gone?
Great article. I have gone through hundreds of articles, finally this gives the comprehensive of...

Rajasekar 24/11/2015 12:27
In response to Import Data From Excel to Access with ASP.NET
While use this code i'm facing on error: "Unrecognized Database format C:\mydabase.accdb" can any...

Parmod 24/11/2015 07:28
In response to ASP.NET 5 Project Basics
For a new learner (Fresher) in ASP.NET there is a issue Fresher have to learn two types of , old...

Robert 22/11/2015 21:35
In response to ASP.NET 5 By Numbers
I have to agree fully with Paul, this does sound like an entire mis-mash of technologies. Sort of in...

Christian 21/11/2015 15:46
In response to MVC 5 with EF 6 in Visual Basic - Creating an Entity Framework Data Model
Many thanks Mike to introduce me in the EF6 Code First way of thinking. Exactly what I need for my...

ax plains 20/11/2015 16:29
In response to Examining the Details and Delete Methods
Hello, really great tutorial for a beginner like me! Is it possible to have an explanation on how a...

Abdul Latif 20/11/2015 14:42
In response to Reading Excel Files Without Saving To Disk In ASP.NET
Could anyone please help me, I am getting : "OfficeOpenXml.ExcelPackage" does not contain a for...