5

Has anyone successfully used extension methods in data-binding expressions?

Say I have an extension method called "GetName" attached to "MyClass".

In the code behind, I have verified this works:

MyClass myObject = new MyClass();   
MyClass.GetName();

However, in a Web form, I try this:

<%@ Import Namespace="My.Namespace" %>

Then, in the ItemTemplate of a Repeater:

<%# ((MyClass)Container.DataItem).GetName() %>

Visual Studio is cool with this, Intellisense agrees with everything, and the project builds. But when I run it, I get:

Compilation Error
'My.Namespace.MyClass' does not contain a definition for 'GetName'

So, the code-behind will accept the extension method, but not the Web form. I suspect it's a name-spacing issue, but I've imported the same namespace in both places.

skaffman
  • 398,947
  • 96
  • 818
  • 769
Deane
  • 8,269
  • 12
  • 58
  • 108

2 Answers2

4

The databinding syntax in aspx/ascx files is notoriously picky. There is a certain amount of parsing that goes on, in particular in this binding area. Look at this example:

This works:

<%# String.Format("{0:C}", DataBinder.Eval("Foo")) %>

But this doesn't:

<%# String.Format("{0:C}", Bind("Foo")) %>

Why? Because while DataBinder.Eval is a real method, Bind is not. Yes, really, it's just a token recognized by the expression binder/parser - it's not actually compiled. I think DataBinder.Eval is probably special-cased for compatibility with ASP.NET 1.1/1.0.

Just to complete the example, the correct way to bind the above expression is to use:

<%# Bind("Foo", "{0:C}") %>

Hope this helps,

Clarification Edit: The C# compiler understands extension methods. The asp.net expression parser does not.

x0n
  • 51,312
  • 7
  • 89
  • 111
  • 2
    While this information might be useful to some people, it really doesn't address the actual question. That said, I also don't know the answer. – SynBiotik Jan 02 '14 at 16:01
  • 1
    @SynBiotik I think the message to take away from my answer is that the compiler understands extension methods, but the asp.net page parser / expression binder does not. Since the syntax is just syntactic sugar for the parser, the compiler will never see it. TL;DR: It is not possible. – x0n Jan 02 '14 at 22:48
4

If you're binding to a collection and want to leverage the strongly typed class MyClass, you can perform the extension in a function in codebehind.

your repeater can use

<%# GetObjectName((MyClass)Container.DataItem) %>

Your CodeBehind will have:

protected string GetObjectName(MyClass obJect)
    {
        return obJect.GetName();
    }

Don't forget to import the namespace of your extension module.

FrumkinWY
  • 173
  • 1
  • 7