¿Cómo crear una función en una plantilla cshtml?

219

Necesito crear una función que solo sea necesaria dentro de un archivo cshtml. Puede pensar en mi situación como métodos de página ASP.NET, que son servicios web mínimos implementados en una página, ya que tienen un alcance de una página. Sé acerca de los ayudantes HTML (métodos de extensión), pero mi función solo es necesaria en un archivo cshtml. No sé cómo crear una firma de función dentro de una vista. Nota : Estoy usando el motor de plantillas Razor.

Saeed Neamati
fuente

Respuestas:

279

Puede usar la directiva @helper Razor:

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

Luego lo invocas así:

@WelcomeMessage("John Smith")
Daniel Liuzzi
fuente
13
No puedes poner etiquetas dentro de los @functionsmétodos, así que me gusta esta respuesta.
jfren484
1
Sí, esto es mucho mejor que declarar una función. Mucho más sencillo.
muglio
2
Pero no puede devolver variables (de ahí la palabra función)
Paul
@Paul No entiendo lo que quieres decir con eso.
Daniel Liuzzi
2
¿Asp.net core también es compatible con @helper?
MuM6oJuM6o
411

¿Por qué no declarar esa función dentro del archivo cshtml?

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

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

fuente
32
Esto debe marcarse como la respuesta, ya que la directiva @functions cumple específicamente con los requisitos de OP. La función Helpers está diseñada para uso compartido en varios archivos de plantilla al colocar el archivo con la directiva @helper en un directorio App_Code. Mientras que, la directiva @functions permite que una función sea utilizada solo por la plantilla que la declara.
Jon Davis
77
También tenga en cuenta que los ayudantes parecen orientados a devolver cadenas al igual que otros ayudantes de afeitar ya lo hacen, y por lo tanto, la functionssolución proporciona más flexibilidad para sus tipos de devolución. Sin embargo, ambas respuestas obtienen +1 en mi libro, ya que ambas son información útil.
AaronLS
8
@AaronLS Para ser justos, los ayudantes no devuelven cadenas, sino IHtmlString, que se encarga de la codificación HTML para usted y protege su aplicación de los ataques XSS. Los ayudantes también le brindan la conveniencia de la sintaxis Razor en el ayudante mismo, que pierde con las funciones. En otras palabras, <p>Welcome, @username.</p>versus return new HtmlString("<p>Welcome, " + Html.Encode(username) + ".</p>");.
Daniel Liuzzi
99
@helpersin embargo, el uso en una sola vista no lo pone a disposición de otras vistas. La razón por la que me gusta más @helper es que puedes poner html entre tus llaves. @functionsno te permite (fácilmente) hacer eso.
jfren484
55
Solo para el registro: ambos @helpery @functionsse pueden compartir entre muchas vistas, y ambos pueden ser declarados y utilizados por una sola vista (y personalmente he encontrado uso para ellos en ambos escenarios compartidos / únicos). En mi humilde opinión, la única diferencia práctica entre ellos es el hecho de que un asistente de vista agrega azúcar sintáctico para devolver fragmentos HTML representados (o, más apropiado, HelperResultinstancias), mientras que una función de vista generalmente solo es útil para devolver tipos de valores o referencias simples.
rsenna
25

Si su método no tiene que devolver html y tiene que hacer otra cosa, puede usar un método lambda en lugar de auxiliar en 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
fuente
3
Funciona, pero está lejos de ser simple. Mi libro sagrado es la simplicidad;). Pero gracias por proporcionar alternativas.
Saeed Neamati
Sin embargo, es útil si necesita acceder a las variables globales de la página en su función, ¿hay alguna otra manera de hacerlo? : /
Alexandre Daubricourt
1

Si desea acceder a las variables globales de su página, puede hacerlo:

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

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

    string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}
Alexandre Daubricourt
fuente
Desde C # 7.0 esta es la única respuesta correcta y correcta. GetLoadingState()Aquí está la función local.
Wolfrevo Cats