Jak utworzyć funkcję w szablonie cshtml?

219

Muszę utworzyć funkcję, która jest niezbędna tylko w jednym pliku cshtml. Możesz myśleć o mojej sytuacji jako o metodach strony ASP.NET, które są minimalnymi usługami sieciowymi zaimplementowanymi na stronie, ponieważ są one ograniczone do jednej strony. Wiem o pomocnikach HTML (metodach rozszerzenia), ale moja funkcja jest potrzebna tylko w jednym pliku cshtml. Nie wiem, jak utworzyć podpis funkcji w widoku. Uwaga : używam silnika szablonów Razor.

Saeed Neamati
źródło

Odpowiedzi:

279

Możesz użyć dyrektywy @helper Razor:

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

Następnie wywołujesz to w ten sposób:

@WelcomeMessage("John Smith")
Daniel Liuzzi
źródło
13
Nie możesz wstawiać tagów do @functionsmetod, więc podoba mi się ta odpowiedź.
jfren484,
1
Tak, jest to o wiele lepsze niż zadeklarowanie funkcji. Znacznie bardziej prosto.
muglio
2
Ale nie można zwrócić zmiennych (stąd funkcja słowa)
Paul
@Paul Nie rozumiem, co masz na myśli.
Daniel Liuzzi
2
Czy rdzeń asp.net obsługuje także @helper?
MuM6oJuM6o
411

dlaczego nie zadeklarować tej funkcji w pliku cshtml?

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

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

źródło
32
Należy to zaznaczyć jako odpowiedź, ponieważ dyrektywa @functions w szczególności spełnia wymagania PO. Funkcja Pomocników jest przeznaczona do wspólnego użytku w wielu plikach szablonów poprzez umieszczenie pliku z dyrektywą @helper w katalogu App_Code. Natomiast dyrektywa @functions pozwala na użycie funkcji tylko przez szablon, który ją deklaruje.
Jon Davis
7
Zwróć też uwagę, że pomocnicy wydają się być zorientowani na zwracanie łańcuchów, tak jak robią to inni pomocnicy maszynek do golenia, a zatem functionsrozwiązanie zapewnia większą elastyczność w zakresie typowania zwrotów. Obie odpowiedzi otrzymują +1 w mojej książce, ponieważ są one użytecznymi ciekawostkami.
AaronLS
8
@AaronLS Szczerze mówiąc, pomocnicy nie zwracają ciągów, ale IHtmlString, które zajmują się kodowaniem HTML i chronią twoją aplikację przed atakami XSS. Pomocnicy zapewniają również wygodę korzystania ze składni Razor w samym pomocniku, którą tracisz z funkcjami. Innymi słowy, w <p>Welcome, @username.</p>porównaniu do return new HtmlString("<p>Welcome, " + Html.Encode(username) + ".</p>");.
Daniel Liuzzi
9
jednak użycie @helperw jednym widoku nie udostępnia go innym widokom. powodem, dla którego lubię @helper, jest to, że możesz umieścić HTML między nawiasami klamrowymi. @functionsnie pozwala (łatwo) na to.
jfren484,
5
Tylko dla porządku: zarówno @helperi @functionsmogą być dzielone między wielu widoków, i oba mogą być zadeklarowane do i używane przez jednego widzenia (i ja osobiście znaleźć zastosowanie dla nich w obu shared / pojedynczych scenariuszy). IMHO jedyną praktyczną różnicą między nimi jest to, że pomocnik widoku dodaje cukier składniowy do zwracania renderowanych fragmentów HTML (lub, bardziej odpowiednio, HelperResultinstancji), podczas gdy funkcja widoku jest zwykle przydatna tylko do zwracania prostych typów referencji lub wartości.
rsenna
25

Jeśli twoja metoda nie musi zwracać html i musi zrobić coś innego, możesz użyć lambda zamiast metody pomocniczej w Razor

@{
    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
źródło
3
Działa, ale dalekie jest od prostoty. Moją świętą księgą jest prostota;). Ale dziękuję za zapewnienie alternatyw.
Saeed Neamati
Jest to przydatne, jeśli chcesz uzyskać dostęp do zmiennych globalnych strony w swojej funkcji, czy jest na to inny sposób? : /
Alexandre Daubricourt
1

Jeśli chcesz uzyskać dostęp do zmiennych globalnych strony, możesz to zrobić:

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

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

    string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}
Alexandre Daubricourt
źródło
Od wersji C # 7.0 jest to jedyna poprawna i poprawna odpowiedź. GetLoadingState()tutaj jest funkcja lokalna.
Wolfrevo Cats