Como criar uma função em um modelo cshtml?

219

Eu preciso criar uma função que é necessária apenas dentro de um arquivo cshtml. Você pode pensar na minha situação como métodos de página do ASP.NET, que são min serviços da Web implementados em uma página, porque têm o escopo definido em uma página. Eu sei sobre auxiliares de HTML (métodos de extensão), mas minha função é apenas necessária em um arquivo cshtml. Não sei como criar uma assinatura de função dentro de uma exibição. Nota : Estou usando o mecanismo de modelo do Razor.

Saeed Neamati
fonte

Respostas:

279

Você pode usar a diretiva @helper Razor:

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

Então você invoca assim:

@WelcomeMessage("John Smith")
Daniel Liuzzi
fonte
13
Você não pode colocar tags dentro dos @functionsmétodos, então eu gosto desta resposta.
jfren484
1
Sim, isso é muito melhor do que declarar uma função. Muito mais direto.
muglio
2
Mas você não pode retornar variáveis ​​(daí a função da palavra) #
Paul
@ Paul Eu não entendo o que você quer dizer com isso.
Daniel Liuzzi
2
O núcleo do asp.net também suporta o @helper?
MuM6oJuM6o 13/08
411

por que não declarar essa função dentro do arquivo cshtml?

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

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

fonte
32
Isso deve ser marcado como a resposta, pois a diretiva @functions atende especificamente aos requisitos de OP. O recurso Helpers é destinado ao uso compartilhado em vários arquivos de modelo, colocando o arquivo com a diretiva @helper em um diretório App_Code. Enquanto a diretiva @functions permite que uma função seja usada apenas pelo modelo que a declara.
Jon Jon Davis
7
Observe também que os auxiliares parecem orientados a retornar seqüências de caracteres, como outros auxiliares de barbear já fazem, e, portanto, a functionssolução fornece mais flexibilidade para seus tipos de retorno. Ambas as respostas recebem +1 no meu livro, pois são informações úteis.
AaronLS
8
@AaronLS Para ser justo, os ajudantes não retornam strings, mas o IHtmlString, que cuida da codificação HTML e protege seu aplicativo contra ataques XSS. Os auxiliares também oferecem a conveniência da sintaxe Razor no próprio auxiliar, que você perde com as funções. Em outras palavras, <p>Welcome, @username.</p>versus return new HtmlString("<p>Welcome, " + Html.Encode(username) + ".</p>");.
Daniel Liuzzi
9
o uso @helperem uma única visualização não a torna disponível para outras visualizações. o motivo pelo qual eu gosto mais do @helper é que você pode colocar o html entre seus aparelhos. @functionsnão (facilmente) permite que você faça isso.
jfren484
5
Apenas para constar: ambos @helpere @functionspodem ser compartilhados entre muitas visões, e ambos podem ser declarados e usados ​​por uma única visão (e eu pessoalmente achei útil para eles em cenários compartilhados / únicos). IMHO, a única diferença prática entre eles é o fato de um auxiliar de exibição adicionar açúcar sintático para retornar trechos de HTML renderizados (ou, mais apropriados, HelperResultinstâncias), enquanto uma função de exibição geralmente é útil apenas para retornar tipos simples de referência ou valor.
rsenna
25

Se o seu método não precisar retornar html e precisar fazer outra coisa, você poderá usar um método lambda em vez do método auxiliar no 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
fonte
3
Funciona, mas está longe de ser simples. Meu livro sagrado é a simplicidade;). Mas obrigado por fornecer alternativas.
Saeed Neamati
É útil, porém, se você precisar acessar as variáveis ​​globais da página em sua função, existe outra maneira de fazer isso? : /
Alexandre Daubricourt 16/02/19
1

Se você deseja acessar as variáveis ​​globais da sua página, pode fazê-lo:

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

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

    string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}
Alexandre Daubricourt
fonte
Desde o C # 7.0, essa é a única resposta correta e correta. GetLoadingState()aqui está a função local.
Wolfrevo Cats