Как создать функцию в шаблоне cshtml?

219

Мне нужно создать функцию, которая необходима только внутри одного файла cshtml. Вы можете думать о моей ситуации как о методах страницы ASP.NET, которые являются минимальными веб-сервисами, реализованными на странице, потому что они ограничены одной страницей. Я знаю о HTML-помощниках (методах расширения), но моя функция просто необходима в одном файле cshtml. Я не знаю, как создать подпись функции внутри представления. Примечание : я использую шаблонизатор Razor.

Саид Нямати
источник

Ответы:

279

Вы можете использовать директиву @helper Razor:

@helper WelcomeMessage(string username)
{
    <p>Welcome, @username.</p>
}

Затем вы вызываете это так:

@WelcomeMessage("John Smith")
Даниэль Лиуцци
источник
13
Вы не можете поместить теги в @functionsметоды, поэтому мне нравится этот ответ.
jfren484
1
Да, это намного лучше, чем декларировать функцию. Гораздо проще.
Muglio
2
Но вы не можете вернуть переменные (отсюда и слово function)
Пол
@ Пол, я не понимаю, что ты имеешь в виду под этим.
Даниэль Лиуцци
2
Поддерживает ли ядро ​​asp.net @helper?
MuM6oJuM6o
411

почему бы просто не объявить эту функцию внутри файла cshtml?

@functions{
    public string GetSomeString(){
        return string.Empty;
    }
}

<h2>index</h2>
@GetSomeString()

источник
32
Это должно быть помечено как ответ, так как директива @functions специально отвечает требованиям OP. Функция Helpers предназначена для совместного использования в нескольких файлах шаблонов путем помещения файла с директивой @helper в каталог App_Code. Принимая во внимание, что директива @functions позволяет использовать функцию только тем шаблоном, который ее объявляет.
Джон Дэвис
7
Также обратите внимание, что помощники кажутся ориентированными на возврат строк, как это делают другие помощники бритвы, и, таким образом, functionsрешение обеспечивает большую гибкость для других типов возврата. Оба ответа получают +1 в моей книге, хотя они оба являются полезными лакомыми кусочками информации.
AaronLS
8
@AaronLS Честно говоря, помощники возвращают не строки, а IHtmlString, которые заботятся о кодировке HTML и защищают ваше приложение от атак XSS. Помощники также дают вам удобство синтаксиса Razor в самом помощнике, который вы теряете из-за функций. Другими словами, <p>Welcome, @username.</p>против return new HtmlString("<p>Welcome, " + Html.Encode(username) + ".</p>");.
Даниэль Лиуцци
9
использование @helperв одном представлении не делает его доступным для других представлений. причина, по которой мне больше нравится @helper, заключается в том, что вы можете поместить html между фигурными скобками. @functionsне (легко) позволяет вам сделать это.
jfren484
5
Только для записи: как @helperи @functionsмогут быть разделены между многими видами, и оба могут быть объявлены в и использоваться одним видом (и я лично нашел применение для них в обоих общих / отдельных сценариев). ИМХО, единственное практическое различие между ними заключается в том, что помощник вида добавляет синтаксический сахар для возврата визуализированных фрагментов HTML (или, что более уместно, HelperResultэкземпляров), тогда как функция представления обычно полезна только для возврата простых типов ссылок или значений.
rsenna
25

Если ваш метод не должен возвращать html и должен делать что-то еще, вы можете использовать лямбда-метод вместо вспомогательного метода в Razor

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";

    Func<int,int,int> Sum = (a, b) => a + b;
}

<h2>Index</h2>

@Sum(3,4)
Мухаммед Хасан Хан
источник
3
Это работает, но это далеко не просто. Моя священная книга - простота;) Но спасибо за предоставление альтернатив.
Саид Нямати
Однако полезно, если вам нужен доступ к глобальным переменным страницы в вашей функции, есть ли другой способ сделать это? : /
Александр Добрикур
1

Если вы хотите получить доступ к глобальным переменным вашей страницы, вы можете сделать это:

@{
    ViewData["Title"] = "Home Page";

    var LoadingButtons = Model.ToDictionary(person => person, person => false);

    string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}
Александр Добрикур
источник
Начиная с C # 7.0 это единственный правильный и правильный ответ. GetLoadingState()здесь локальная функция.
Wolfrevo Cats