Bagaimana cara membuat fungsi dalam template cshtml?

219

Saya perlu membuat fungsi yang hanya diperlukan di dalam satu file cshtml. Anda dapat menganggap situasi saya sebagai metode halaman ASP.NET, yang merupakan layanan web minimal yang diterapkan dalam satu halaman, karena mereka mencakup satu halaman. Saya tahu tentang pembantu HTML (metode ekstensi), tetapi fungsi saya hanya diperlukan dalam satu file cshtml. Saya tidak tahu cara membuat tanda tangan fungsi di dalam tampilan. Catatan : Saya menggunakan mesin template Razor.

Saeed Neamati
sumber

Jawaban:

279

Anda dapat menggunakan petunjuk @helper Razor:

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

Lalu Anda memintanya seperti ini:

@WelcomeMessage("John Smith")
Daniel Liuzzi
sumber
13
Anda tidak dapat memasukkan tag ke dalam @functionsmetode, jadi saya suka jawaban ini.
jfren484
1
Ya ini jauh lebih baik daripada mendeklarasikan suatu fungsi. Jauh lebih lurus ke depan.
muglio
2
Tetapi Anda tidak dapat mengembalikan variabel (karena itu kata berfungsi)
Paul
@ Paul Saya tidak mengerti apa yang Anda maksud dengan itu.
Daniel Liuzzi
2
Apakah core asp.net juga mendukung @helper?
MuM6oJuM6o
411

mengapa tidak mendeklarasikan fungsi itu di dalam file cshtml?

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

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

sumber
32
Ini harus ditandai sebagai jawabannya, karena arahan @functions secara khusus memenuhi persyaratan OP. Fitur Pembantu dimaksudkan untuk digunakan bersama di beberapa file templat dengan meletakkan file dengan direktif @helper ke direktori App_Code. Sedangkan, direktif @functions memungkinkan fungsi hanya digunakan oleh templat yang menyatakannya.
Jon Davis
7
Perhatikan juga helper sepertinya berorientasi untuk mengembalikan string seperti yang sudah dilakukan helper, dan dengan demikian functionssolusinya memberikan lebih banyak fleksibilitas untuk tipe return toher. Kedua jawaban mendapatkan +1 di buku saya karena keduanya adalah informasi berguna yang bermanfaat.
AaronLS
8
@ AaronLS Agar adil, pembantu tidak mengembalikan string tetapi IHtmlString, yang menangani pengodean HTML untuk Anda dan melindungi aplikasi Anda dari serangan XSS. Pembantu juga memberi Anda kemudahan sintaks Razor dalam helper itu sendiri, yang Anda kehilangan fungsinya. Dengan kata lain, <p>Welcome, @username.</p>versus return new HtmlString("<p>Welcome, " + Html.Encode(username) + ".</p>");.
Daniel Liuzzi
9
menggunakan @helperdalam satu tampilan tidak membuatnya tersedia untuk tampilan lain. alasan saya suka @helper lebih baik adalah Anda dapat menempatkan html di antara kurung kurawal Anda. @functionstidak (dengan mudah) membiarkan Anda melakukan itu.
jfren484
5
Sekadar catatan: keduanya @helperdan @functionsdapat dibagikan di antara banyak tampilan, dan keduanya dapat dideklarasikan dan digunakan oleh satu tampilan (dan saya secara pribadi telah menemukan penggunaannya dalam kedua skenario bersama / tunggal). IMHO satu-satunya perbedaan praktis di antara mereka adalah kenyataan bahwa view helper menambahkan gula sintaksis untuk mengembalikan potongan HTML yang diberikan (atau, lebih tepat, HelperResultinstance), sementara fungsi tampilan biasanya hanya berguna untuk mengembalikan referensi sederhana atau tipe nilai.
rsenna
25

Jika metode Anda tidak harus mengembalikan html dan harus melakukan sesuatu yang lain maka Anda dapat menggunakan lambda alih-alih metode pembantu di 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
sumber
3
Ini bekerja, tetapi jauh dari kesederhanaan. Buku suci saya adalah kesederhanaan;). Tetapi terima kasih telah memberikan alternatif.
Saeed Neamati
Ini berguna meskipun jika Anda perlu mengakses variabel global halaman di fungsi Anda, apakah ada cara lain untuk melakukannya? : /
Alexandre Daubricourt
1

Jika Anda ingin mengakses variabel global halaman Anda, Anda dapat melakukannya:

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

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

    string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}
Alexandre Daubricourt
sumber
Sejak C # 7.0 ini adalah satu-satunya jawaban yang tepat dan benar. GetLoadingState()di sini adalah fungsi lokal.
Wolfrevo Cats