Autor en Google+
Saltar al contenido

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

10 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, ASP.NET Core, MVC, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
jueves, 2 de junio de 2011
ASP.NET MVCEs bastante frecuente necesitar obtener el identificador o nombre de un control de entrada que ha sido generado por un helper de ASP.NET MVC. Por ejemplo, si queremos acceder desde scripts al contenido de un cuadro de texto creado de esta forma, obligatoriamente debemos conocer con exactitud qué identificador le asignó el sistema.

Observad el siguiente código de vista, bastante trivial:
@Html.EditorFor(model=>model.Nombre)
Intuitivamente podemos estar seguros de que el control será generado con “Nombre” como nombre de campo e identificador. El código creado será algo así, poco más o menos:
<input type="text" name="Nombre" id="Nombre" />
De esta forma, podríamos acceder al contenido del cuadro de texto por ejemplo con el script mostrado a continuación, que se encarga de convertir su contenido en mayúsculas cuando pierde el foco:
<script type="text/javascript">
    $("#Nombre").blur(function () {
        var mays = $(this).val().toUpperCase();
        $(this).val(mays);
    });
</script>
Y funcionar, funcionaría… algunas veces ;-)

Hay muchos escenarios en los que no está tan claro el identificador que será asignado, sobre todo si estamos generando controles de edición para propiedades de tipos complejos, en vistas parciales, o cuando estamos creando editores personalizados para utilizar con Html.EditorFor(). Este último caso además es especialmente complicado, puesto que desconocemos por completo el nombre de la propiedad para la cual será utilizado.

Lo que suelo hacer en estos casos es utilizar estos dos pequeños helpers, Html.IdFor() y Html.NameFor(), que permiten obtener el nombre e identificador asignado a una propiedad del Modelo accediendo a sus metadatos:

public static class HtmlHelpers
{
    public static string IdFor<TModel, TProperty>(this HtmlHelper<TModel> html, 
        Expression<Func<TModel, TProperty>> expression)
    {
        string propiedad = ExpressionHelper.GetExpressionText(expression);
        return html.ViewData.TemplateInfo.GetFullHtmlFieldId(propiedad);
    }
 
    public static string NameFor<TModel, TProperty>(this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> expression)
    {
        string propiedad = ExpressionHelper.GetExpressionText(expression);
        return html.ViewData.TemplateInfo.GetFullHtmlFieldName(propiedad);
    }
}

De esta forma, podemos reescribir el script anterior asegurando la corrección del identificador utilizado indicando la propiedad mediante una expresión lambda con tipado fuerte, como solemos hacer en los helpers de edición:
<script type="text/javascript">
    $("#@Html.IdFor(model=>model.Nombre)").blur(function () {
        var mays = $(this).val().toUpperCase();
        $(this).val(mays);
    });
</script>
Y aunque es menos frecuente, también podemos encontrarnos con la necesidad de obtener el nombre de campo del formulario (atributo “name”) a utilizar para un control de edición. Por ejemplo, si queremos construir de forma manual las etiquetas, podemos establecer el nombre utilizando Html.NameFor():
<input type="text" 
       id="@Html.IdFor(model=>model.Nombre)" 
       name="@Html.NameFor(model=>model.Nombre)" />
Espero que os sea de utilidad.

Publicado en: Variable not found.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

2 Comentarios:

Mauricio Sola dijo...

Hola José, como estás?
Te cuento que éstas extensiones ya son provistas por el framework:

Las encontrás en:

Microsoft.Web.Mvc.NameExtensions.IdFor()
Microsoft.Web.Mvc.NameExtensions.NameFor()

Espero les sirva este tip.
Saludos!

José M. Aguilar dijo...

Hola, mauricio!

Sí, lo sé, han sido incluidos en mvc4, pero no existían en el momento de escribir este artículo :-)

Saludos y gracias por aportar!