Wie erstelle ich eine Funktion in einer cshtml-Vorlage?

219

Ich muss eine Funktion erstellen, die nur in einer cshtml-Datei erforderlich ist. Sie können sich meine Situation als ASP.NET-Seitenmethoden vorstellen, bei denen es sich um minimale Webdienste handelt, die auf einer Seite implementiert sind, da sie auf eine Seite beschränkt sind. Ich kenne HTML-Helfer (Erweiterungsmethoden), aber meine Funktion wird nur in einer cshtml-Datei benötigt. Ich weiß nicht, wie man eine Funktionssignatur in einer Ansicht erstellt. Hinweis : Ich verwende die Razor Template Engine.

Saeed Neamati
quelle

Antworten:

279

Sie können die @ helper Razor-Direktive verwenden:

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

Dann rufen Sie es so auf:

@WelcomeMessage("John Smith")
Daniel Liuzzi
quelle
13
Sie können keine Tags in die @functionsMethoden einfügen, daher gefällt mir diese Antwort.
jfren484
1
Ja, das ist viel besser als eine Funktion zu deklarieren. Viel einfacher.
Muglio
2
Aber Sie können keine Variablen zurückgeben (daher die Wortfunktion)
Paul
@ Paul Ich verstehe nicht, was du damit meinst.
Daniel Liuzzi
2
Unterstützt asp.net Core auch den @helper?
MuM6oJuM6o
411

Warum nicht einfach diese Funktion in der cshtml-Datei deklarieren?

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

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

quelle
32
Dies sollte als Antwort markiert werden, da die @ functions-Direktive speziell die OP-Anforderungen erfüllt. Die Helpers-Funktion ist für die gemeinsame Verwendung in mehreren Vorlagendateien vorgesehen, indem die Datei mit der @ helper-Direktive in ein App_Code-Verzeichnis gestellt wird. Während die @ functions-Direktive zulässt, dass eine Funktion nur von der Vorlage verwendet wird, die sie deklariert.
Jon Davis
7
Beachten Sie auch, dass Helfer wie andere Rasiermesserhelfer darauf ausgerichtet zu sein scheinen, Zeichenfolgen zurückzugeben, und daher functionsbietet die Lösung mehr Flexibilität für andere Rückgabetypen. Beide Antworten erhalten in meinem Buch jedoch +1, da sie beide nützliche Informationen sind.
AaronLS
8
@AaronLS Um fair zu sein, geben Helfer keine Zeichenfolgen zurück, sondern IHtmlString, die sich um die HTML-Codierung für Sie kümmern und Ihre App vor XSS-Angriffen schützen. Helfer bieten Ihnen auch die Bequemlichkeit der Razor-Syntax im Helfer selbst, die Sie mit Funktionen verlieren. Mit anderen Worten, <p>Welcome, @username.</p>versus return new HtmlString("<p>Welcome, " + Html.Encode(username) + ".</p>");.
Daniel Liuzzi
9
Die Verwendung @helperin einer einzelnen Ansicht macht es jedoch nicht für andere Ansichten verfügbar. Der Grund, warum ich @helper besser mag, ist, dass Sie HTML zwischen Ihre geschweiften Klammern setzen können. @functionslässt dich das nicht (leicht) machen.
jfren484
5
Nur zur Veranschaulichung: Beide @helperund @functionskönnen von vielen Ansichten gemeinsam genutzt werden, und beide können in einer einzelnen Ansicht deklariert und von dieser verwendet werden (und ich habe persönlich festgestellt, dass sie in beiden gemeinsam genutzten / einzelnen Szenarien verwendet werden können). IMHO ist der einzige praktische Unterschied zwischen ihnen die Tatsache, dass ein Ansichtshelfer syntaktischen Zucker für die Rückgabe gerenderter HTML-Snippets (oder besser gesagt HelperResultInstanzen) hinzufügt , während eine Ansichtsfunktion normalerweise nur für die Rückgabe einfacher Referenz- oder Werttypen nützlich ist.
Rsenna
25

Wenn Ihre Methode kein HTML zurückgeben muss und etwas anderes tun muss, können Sie in Razor ein Lambda anstelle einer Hilfsmethode verwenden

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

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

<h2>Index</h2>

@Sum(3,4)
Muhammad Hasan Khan
quelle
3
Es funktioniert, aber es ist alles andere als einfach. Mein heiliges Buch ist Einfachheit;). Aber danke, dass Sie Alternativen anbieten.
Saeed Neamati
Es ist jedoch nützlich, wenn Sie in Ihrer Funktion auf die globalen Variablen der Seite zugreifen müssen. Gibt es eine andere Möglichkeit, dies zu tun? : /
Alexandre Daubricourt
1

Wenn Sie auf die globalen Variablen Ihrer Seite zugreifen möchten, können Sie Folgendes tun:

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

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

    string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}
Alexandre Daubricourt
quelle
Seit C # 7.0 ist dies die einzig richtige Antwort. GetLoadingState()Hier ist die lokale Funktion.
Wolfrevo Cats