Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 9 de febrero de 2016
ASP.NET CorePues a estas alturas, no son pocos los posts que hemos ido publicado por aquí sobre características que cambian o desaparecen en el salto a las nuevas tecnologías "core", pero no se vayan todavía, aún hay más ;)

En esta ocasión, comentaremos muy brevemente una gran ausencia en las vistas Razor: la directiva @helper, que no estará disponible en la primera versión de ASP.NET Core MVC.

<Disclaimer>Aunque en una Release Candidate las cosas no deberían cambiar, ya han demostrado bastantes veces que sí que cambian, por lo que algo de lo que digamos aquí podría no ser cierto en la versión final del producto</Disclaimer>

Esto no es un tema reciente: hace ya bastantes meses, la implementación que había era bastante incompleta y no encajaba bien en la nueva arquitectura, por lo que tras algunos debates y reuniones de diseño, se decidió que lo mejor era eliminar esta directiva.


Personalmente me parece una gran ausencia, porque las usaba bastante para evitar porciones de código repetido en el interior de mis vistas, y también para facilitar el mantenimiento o legibilidad cuando éstas eran relativamente complejas, pero bueno, es lo que hay.

Pero este nuevo escenario, aún tenemos posibilidades al alcance para conseguir un resultado parecido al que lográbamos con la directiva @helper , como:
  • Usar la directiva @functions para crear funciones helper en las vistas, quizás combinado con interpolación de cadenas de C#  y heredoc en caso de haber mucho HTML:
    @Input("Name", "name", "José")
    
    @functions {
    
        HtmlString Input(string label, string field, string value)
        {
            var result = $@"
                <div class='input-group'>
                    <label for='{field}'>{label}</label>
                    <input type='text' name='{field}' id='{field}'
                           value='{value}'>
                </div>
            ";
            return new HtmlString(result);
        }
    }
  • Por supuesto, si el helper lo vamos a utilizar más allá de una única vista, ese mismo código podríamos desplazarlo a una clase estática y crearlo como extensor de IHtmlHelper para poder usarlo en la forma @Html.MyHelper()  desde las vistas. 
    public static class MyHtmlExtensions
    {
        public static HtmlString Input(
               this IHtmlHelper helper, string label, 
               string field, string value)
        {
            var result = $@"
            <div class='input-group'>
                <label for='{field}'>{label}</label>
                <input type='text' name='{field}' id='{field}' 
                       value='{value}'>
            </div>
            ";
            return new HtmlString(result);
        }
    }
  • Otra posibilidad, que ya teníamos en versiones anteriores de MVC, es llevar el código del helper a una vista parcial independiente e invocarla desde la vista principal con @Html.Partial(). La pega de este enfoque es que es algo farragoso, pues a la hora de pasar parámetros a esta parcial hay que crear un view model, o bien jugar con dynamics.
    @Html.Partial("_Input", new InputViewModel() { 
            Field="name", 
            Label="Name", 
            Value="José" })
  • Por último, podríamos utilizar también los nuevos View Components, de los que hablaremos un día de estos por aquí. Aunque a priori parecen los sustitutos naturales de los helpers HTML, es igual o incluso más farragoso que el enfoque anterior, pues es necesario crear el componente, la vista (ubicada en el lugar indicado por la convención) y realizar la llamada desde la vista mediante un objeto anónimo:
    @Component.InvokeAsync("Input", 
               new { label="Name", field="name", value="José" }
    )
    

The helper directive is not supportedPero bueno, no todo son malas noticias: muy probablemente traigan la directiva @helper de vuelta en un  futuro no demasiado lejano, por lo que "helper" sigue siendo una palabra reservada y reconocida por el parser.

Esto se ve claramente al utilizarla Visual Studio, que nos indica que está reconociendo la directiva pero no está soportada, a diferencia del error que aparecería si usamos cualquier otra directiva inexistente.

Publicado en Variable not found.

2 Comentarios:

Unknown dijo...

Hola !!

Puede ser que tampoco este la directiva @Ajax ? Me estoy volviendo loco para utilizarla y no veo la manera...

Saludos !!

José María Aguilar dijo...

Hola!

Hasta donde he visto, el helper @Ajax no existirá tampoco en Core MV, supongo que por que ataba demasiado a jQuery. Personalmente no me afecta demasiado porque hace mucho que no lo uso, pero a los que lo utilizáis seguro que os hace una faena.

En cualquier caso, seguro que aparecen tag helpers especializados para que las etiquetas "normales" tomen un comportamiento Ajax (por ejemplo, añadiéndoles un asp-mode="ajax"... o cosas así).

Saludos!