Как передать лямбда методу хладагента Razor?
У меня есть вспомогательный метод бритвы, который нужно взять в Func<>
, который вернет некоторый HTML-контент для печати. Это то, что я изначально имел:
@helper node(string title, Func<HelperResult> descriptions)
{
....
<div>@descriptions()</div>
....
}
@node("title",
new Func<HelperResult>(() =>
{
return new HelperResult(
@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>);
}))
К сожалению, мой текст никогда не распечатывается. Нет ошибки.
Итак, я узнал о встроенных помощниках и изменил вызывающий метод на это:
@node("title",
@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>)
Однако теперь я получаю ошибку компиляции, говоря
"Делегат" System.Func "не возьмите 1 аргумент".
Но я не принимаю никаких аргументов.
Итак, если я изменю его на Func<object,HelperResult>
, а затем вызову его с помощью @descriptions(null)
, я получаю следующую ошибку:
"Невозможно использовать лямбда-выражение в качестве аргумента динамически отправленную операцию без предварительного литья ее делегату или тип дерева выражений"
Я уверен, что у меня что-то не так, но я не уверен, что это такое.
Изменить. Я думаю, что я, возможно, решил эту проблему, но она представляет некоторые другие проблемы.
То, что я сделал, - это бросить лямбду, прежде чем перейти к динамическому методу. Я предполагаю, что ошибка пыталась сказать:
@node("title",
((Func<dynamic, HelperResult>)(@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>))
Это работает, и он корректно печатает теги span
. К сожалению, я должен передать бесполезный параметр при вызове Func
.
Теперь проблема заключается в том, что моя реальная функция немного больше, чем просто написать некоторые пробелы. Это примерно так:
@node("title",
((Func<dynamic, HelperResult>)(@<text>
<span>@Helpers.Format(resource.Description,"item")</span>
</text>))
Где @Helpers.Format
- еще один помощник, а ресурс - (динамическая) переменная из модели страницы.
Конечно, теперь код выполняется, но ничего не распечатывается (внутри тега <span>
). Я поставил точку останова внутри моей вспомогательной функции Format
, и она попадает в нее, и все параметры правильно установлены, поэтому я не уверен, почему она не будет выводиться правильно. Аналогично, если я просто изменю его на resource.Description
то ничего не получается.
Поскольку он хорошо работает вне этого контекста, мне интересно, не помогают ли встроенные помощники Razor внешние переменные?
Ответы
Ответ 1
На самом деле HelperResult - это то, что Microsoft предпочла бы вам не использовать, о чем свидетельствует документация:
public class HelperResult: IHtmlString в пространстве имен System.Web.WebPages
Сводка: этот тип/член поддерживает инфраструктуру .NET Framework и не предназначен для использования непосредственно из вашего кода.
Возможное решение вашей проблемы может заключаться в том, чтобы обернуть функцию описания в другой помощник, а затем передать этот помощник в качестве группы методов вашему помощнику node, например это:
@helper Node(string title, Func<HelperResult> descriptions)
{
<div>@descriptions()</div>
}
@helper Description() {
<span>desc1</span>
<span>desc2</span>
}
@Node("title", Description)
В любом случае ваша первая идея не должна работать, потому что параметр типа Func на самом деле равен параметру без параметров, и в этом случае вам нужно написать выражение лямбда следующим образом:
myFunction( () => doSomething)
Таким образом, ваш вызов функции был бы следующим:
@node("title", () =>
@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>)
Поскольку будущее этих помощников немного сомнительно, я бы подумал о переключении на HtmlHelpers для небольших фрагментов html или Partials для больших фрагментов.
Ответ 2
@Test(new Func<object, HelperResult>[]{@<text>hello</text>})
@Test(new Func<object, HelperResult>[]{@<text>hello</text>,@<text>world</text>})
@helper Test(params Func<object, HelperResult>[] results)
{
foreach (var result in results)
{
@result(null);
}
}