Подтвердить что ты не робот

Как передать лямбда методу хладагента 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 внешние переменные?

4b9b3361

Ответ 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);
    }
}