Как вы используете методы расширения в выражениях привязки данных веб-формы?

Кто-нибудь успешно использовал методы расширения в выражениях привязки данных?

Скажем, у меня есть метод расширения под названием «GetName», прикрепленный к «MyClass».

В коде позади я проверил, что это работает:

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

Однако в веб-форме я пытаюсь сделать следующее:

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

Затем в ItemTemplate повторителя:

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

Visual Studio с этим справляется, Intellisense со всем соглашается, и проект строится. Но когда я запускаю его, я получаю:

Ошибка компиляции
"My.Namespace.MyClass" не содержит определения для "GetName"

Таким образом, код программной части будет принимать метод расширения, но не веб-форму. Я подозреваю, что это проблема с интервалом между именами, но я импортировал одно и то же пространство имен в обоих местах.


person Deane    schedule 02.09.2009    source источник
comment
Наконец, я нашел решение на stackoverflow.com/a/486913/2119731.   -  person rodrigo ratan    schedule 19.09.2020


Ответы (2)


Синтаксис привязки данных в файлах aspx/ascx известен своей привередливостью. Происходит определенный объем синтаксического анализа, в частности, в этой области привязки. Посмотрите на этот пример:

Это работает:

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

Но это не так:

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

Почему? Потому что, хотя DataBinder.Eval и является реальным методом, Bind им не является. Да, действительно, это просто токен, распознаваемый выражением binder/parser — на самом деле он не компилируется. Я думаю, что DataBinder.Eval, вероятно, предназначен для совместимости с ASP.NET 1.1/1.0.

Чтобы завершить пример, правильный способ связать приведенное выше выражение — использовать:

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

Надеюсь это поможет,

Пояснение Edit: компилятор C# понимает методы расширения. Анализатор выражений asp.net этого не делает.

person x0n    schedule 02.09.2009
comment
Хотя эта информация может быть полезна для некоторых людей, на самом деле она не затрагивает фактический вопрос. Тем не менее, я также не знаю ответа. - person SynBiotik; 02.01.2014
comment
@SynBiotik Я думаю, что сообщение, которое следует извлечь из моего ответа, заключается в том, что компилятор понимает методы расширения, а анализатор страниц asp.net / связыватель выражений - нет. Поскольку синтаксис — это просто синтаксический сахар для парсера, компилятор его никогда не увидит. TL;DR: это невозможно. - person x0n; 03.01.2014

Если вы привязываетесь к коллекции и хотите использовать строго типизированный класс MyClass, вы можете выполнить расширение в функции в отделенном коде.

ваш репитер может использовать

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

Ваш CodeBehind будет иметь:

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

Не забудьте импортировать пространство имен вашего модуля расширения.

person FrumkinWY    schedule 03.04.2014