[StringLength]
, y sin embargo, los helpers habituales no generen el atributo maxlength
en el tag <input type="text">
.Podemos comprobarlo muy fácilmente. Por ejemplo, dada una entidad del Modelo como la siguiente:
public class Persona
{
[StringLength(20, ErrorMessage="Máximo {1} caracteres")]
public string Nombre { get; set; }
}
maxlength
de la etiqueta el tag <input type="text">
.Afortunadamente hay varias formas de solucionar este pequeño inconveniente, como creando nuevos helpers o utilizando plantillas de edición personalizadas. En este post veremos cómo implementar la primera opción, creando un helper que realice la tarea de forma automática.
Html.LimitedTextBoxFor()
Vale, sé que no es un nombre estupendo para el helper, pero de momento va a tener que valer con ese ;-P. La idea es que podamos generar text boxes que limiten el número de caracteres permitidos en función de lo indicado en las anotaciones del Modelo. Es decir, sobre el ejemplo anterior, ocurriría lo siguiente:// En la vista:
<%= Html.LimitedTextBoxFor(model => model.Nombre ) %>
// HTML resultante:
<input id="Nombre" maxlength="20" name="Nombre" type="text" value="" />
El código del helper es el siguiente, y lo comento brevemente justo a continuación:
public static MvcHtmlString LimitedTextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty>> expression,
IDictionary<string, object> htmlAttributes)
{
// Obtenemos los metadatos de la propiedad
ModelMetadata metadata =
ModelMetadata.FromLambdaExpression(expression, html.ViewData);
// Obtenemos la información utilizada para validar el tamaño del texto
ControllerContext cctx = html.ViewContext.Controller.ControllerContext;
StringLengthAttributeAdapter stringLengthValidator =
metadata.GetValidators(cctx)
.OfType<StringLengthAttributeAdapter>()
.FirstOrDefault();
if (stringLengthValidator != null)
{ // Si hay validación de este tipo...
var parms = stringLengthValidator
.GetClientValidationRules()
.First()
.ValidationParameters;
// Obtenemos el valor del
int maxlength = (int)parms["maximumLength"]; // tamaño máximo para el texto...
if (htmlAttributes == null)
htmlAttributes = new RouteValueDictionary();
htmlAttributes.Add("maxlength", maxlength); // y añadimos el atributo maxlength
}
return html.TextBoxFor(expression, htmlAttributes);
}
En primer lugar, estamos accediendo a los metadatos de la propiedad partiendo de la expresión lambda que recibimos como parámetro. Desde estos metadatos obtenemos, si existe, el validador asociado al atributo
[StringLength]
, que es de tipo StringLengthAttributeAdapter
.Una vez obtenido el validador, buscamos en éste la información que será suministrada a los scripts en cliente, en particular el valor del parámetro “maximumLength”, introduciéndolo en la colección de atributos HTML que finalmente se envía al helper original asociando este valor al atributo
maxlength
de la etiqueta a generar. Ahora, para simplificar las llamadas al helper desde las vistas, creamos un par de sobrecargas, similares a las que utilizamos normalmente en
TextBoxFor()
:public static MvcHtmlString LimitedTextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes)
{
return html.LimitedTextBoxFor<TModel, TProperty>(
expression,
((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes))
);
}
public static MvcHtmlString LimitedTextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty>> expression)
{
return html.LimitedTextBoxFor(expression, null);
}
Y eso es todo. Si sustituimos en nuestras vistas las llamadas a
TextBoxFor
por LimitedTextBoxFor
tendremos la cuestión solucionada. Otra posibilidad, bastante más cómoda, sería retocar las plantillas de edición generadas por Visual Studio para que incluyan las llamadas a estos nuevos helpers.Podéis encontrar el código fuente completo en Skydrive.
Publicado en: Variable not found.
Hey, ¿sabes que estoy en Twitter?
Publicado por José M. Aguilar a las 11:47 p. m.
Etiquetas: asp.net, aspnetmvc, desarrollo, trucos
- Interesante comparativa entre ASP.NET MVC y Rails.
I recently was contacted to implement an ASP.NET MVC application and I saw this as a great opportunity to compare it with Rails3. What immediately strikes you
Fuente: blog.jayway.com | Fecha: 23/04/2010 - Configurar VS2010 para permitir la depuración en el interior del código de .NET framework.
Fuente: weblogs.asp.net | Fecha: 23/04/2010 - Uso de áreas portables (MvcContrib). Extracto del libro "ASP.NET MVC 2 in action".
Los Techies - Code like a rabid donkey!
Fuente: http://www.lostechies.com/ | Fecha: 23/04/2010 - Los controladores MVC, a dieta: sólo hay que ceñirse a las responsabilidades de la capa.
Fuente: Matt Hinze | Fecha: 22/04/2010 - Gestión de excepciones en acciones JSON bajo MVC 2.
The site covers technical articles on Microsoft.NET, ASP.NET, MVC, C#, VB.NET, jQuery, AJAX, JavaScript, Silverlight, LINQ, VSTS, .NET Interview Questions, Windows Forms, Expression Web, Office 2007, Vista and related technologies
Fuente: http://www.dotnetcurry.com/ | Fecha: 22/04/2010 - Screencast de Hadi Hariri comentando las ayudas de Resharper 5 para ASP.NET.
This screen cast shows some of the ASP.NET Features ReSharper offers in version 5. It applies to both ASP.NET MVC and WebForms.
Fuente: hadihariri.com | Fecha: 22/04/2010 - Espectaculares mejoras en el depurador de Visual Studio 2010.
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 22/04/2010 - Snippets de código para ASP.NET MVC 2 en Visual Studio 2010.
VS 2010 comes with ready made snippets which helps you save time while coding.You insert a snippet by typing the name of the code snippet and hitting the Tab key twice. You can also use the following method if you wish to see a listing of snippets available.
Fuente: weblogs.asp.net | Fecha: 21/04/2010 - Referencia rápida de Application Recovery and Restart (ARR), que permite salvar y recuperar el estado de una aplicación ante una parada inesperada o cuelgue.
Application Recovery and Restart (ARR) is a feature that allows you to prepare for the impossible (?) case where your application crash or waits forever (“Not Responding”)
Fuente: blogs.microsoft.co.il | Fecha: 21/04/2010 - Publicada la Microsoft Enterprise Library v5.0.
Todo lo que los geeks de Windows y .Net tienen que contar en sus blogs y en nuestros foros
Fuente: geeks.ms | Fecha: 21/04/2010 - Especificaciones del lenguaje Visual Basic 10.0.
The Microsoft Word document download requires 1.6 MB of disk space to download and install. It also requires Microsoft Word or Microsoft Word Viewer to view.
Fuente: http://www.microsoft.com/ | Fecha: 21/04/2010 - Especificaciones del lenguaje C# 4.0.
The Microsoft Word document download requires 2.5 MB of disk space to download and install. It also requires Microsoft Word or Microsoft Word Viewer to view.
Fuente: http://www.microsoft.com/ | Fecha: 21/04/2010 - Solución a problemas comunes del SEO utilizando la extensión URL rewrite.
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 21/04/2010 - Habilitar la compilación de vistas MVC en TFS 2010.
When you create a View for an ASP.NET MVC web application, you add an .ASPX or .ASCX file that uses the ASP.NET engine to render a combination of mark-up and code. Unfortunately, those Views don’t get compiled until IIS renders them for your web site
Fuente: blogs.msdn.com | Fecha: 21/04/2010 - Un vistazo rápido a las novedades de HTML 5.
Overview of the new HTML5
Fuente: http://www.slideshare.net/ | Fecha: 20/04/2010 - Uso de recursos incrustados en áreas portables utilizando el Embedded Resource Controller de MvcContrib.
MvcContrib contains a feature called Portable Areas which I’ve recently blogged about. In short, portable areas provide a way to distribute MVC binary components as simple .NET assemblies where the aspx/ascx files are actually compiled into the assembly as embedded resources. ...
Fuente: geekswithblogs.net | Fecha: 19/04/2010 - Protección contra ataques CSRF utilizando el atributo AntiforgeryToken de ASP.NET MVC.
Fuente: weblogs.asp.net | Fecha: 19/04/2010 - Ejemplo sobre cómo utilizar el API de TinyUrl con ASP.NET MVC.
Todo lo que los geeks de Windows y .Net tienen que contar en sus blogs y en nuestros foros
Fuente: geeks.ms | Fecha: 19/04/2010 - Utilizar el API de datos de Google: acceso a la información de Google Analytics
It's really amazing that Google let developers access and use its services data via GData easily. It's really easy to interact with services like Calendar, Analytics, Google Reader, Blogger,YouTube, etc. ...
Fuente: mahdi.mp | Fecha: 19/04/2010 - ¿Se puede escribir código claro sin necesidad de usar comentarios?
Eliminating Comments: the Road to Clarity
Fuente: elegantcode.com | Fecha: 19/04/2010 - ¿Qué ocurre con los parámetros opcionales de C# 4.0 cuando compilas para .NET 3.5?
Something you may not know is that Visual Studio 2010 will let you compile this against .NET 3.5, with no error or warning.
Fuente: weblogs.asp.net | Fecha: 16/04/2010 - Generar un feed RSS desde ASP.NET MVC con un ActionResult personalizado.
When building a website it is common to expose an RSS/ATOM feed for your content. Feeds serve two main purposes. The first, is that it allows other sites to consume your content for syndication. For example ...
Fuente: dotnet.dzone.com | Fecha: 16/04/2010 - Cómo enviar datos JSON a controladores MVC con jQuery.
This blog has personalition features for you, the reader. Below is a key of what all the icons mean and which aspects of the layout they change.
Fuente: lozanotek.com | Fecha: 16/04/2010 - ScottGu comenta el lanzamiento de Silverlight 4.
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 16/04/2010 - NoSQL con MongoDB, NoRM y ASP.NET MVC.
Shiju Varghese's Blog on ASP.NET MVC
Fuente: weblogs.asp.net | Fecha: 16/04/2010 - Hanselman comenta algunos breaking changes en ASP.NET 4 (= cosas con las que hay que tener cuidado).
Scott Hanselman on Programming, User Experience, The Zen of Computers and Life in General
Fuente: http://www.hanselman.com/ | Fecha: 13/04/2010 - Visual Studio 2010 en español será publicado en el mes de Mayo.
Fuente: twitter.com | Fecha: 13/04/2010 - ¿Por qué no existe un Visual Studio 2010 específico para 64 bits?
Disclaimer: This is yet another of my trademarked "approximately correct" discussions From time to time customers or partners ask me about our plans to create a 64 bit version of Visual Studio. When is it coming? Why aren’t we making it a priority? Haven’t
Fuente: blogs.msdn.com | Fecha: 13/04/2010 - Model Binding seguro y sencillo en ASP.NET MVC utilizando interfaces.
A little over a year ago (wow, it seems like only yesterday), I made a post called Think Before You Bind. In this post, I presented to you exactly why you want to make sure that when you are doing automatic ...
Fuente: http://www.codethinked.com/ | Fecha: 13/04/2010 - El día D: lanzado Visual Studio 2010 y NET 4.
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 13/04/2010
Publicado en: Variable not found
Si trabajamos con un array, podemos consultar la propiedad
Length
; si se trata de una colección, podemos utilizar la propiedad Count
, que también nos devolverá el mismo dato de forma directa.Sin embargo, cuando procesamos información es frecuente tratar con tipos de datos enumerables cuya implementación exacta desconocemos, y en los que no tenemos acceso a ninguna propiedad que nos permita conocer el número de elementos exactos que tiene almacenados. Por ejemplo, esto ocurre cuando obtenemos un conjunto de datos en forma de
IEnumerable
o trabajamos con LINQ sobre alguna fuente de información.Pues bien, en estos casos hay que ser algo prudentes con la forma de consultar el número de elementos. Me he topado con código
Count()
, facilitado por LINQ para las enumeraciones y otras colecciones de datos, con objeto de saber si una lista estaba vacía:var prods = services.GetProductsByCategory(category);
if (prods.Count() > 0)
{
// Hacer algo con los elementos de la lista
}
else
{
// No hay elementos
}
Seguro que ya os habréis percatado de que eso está mal, muy mal. El método
Count()
recorrerá uno por uno los elementos para contarlos, retornando el número exacto de ellos. En escenarios de un gran número de elementos, o cuando es costoso obtener cada elemento (como al traerlos de una base de datos) puede suponer un consumo de recursos enorme.Y justo por esto existe el método
Any()
, que comprueba únicamente si existe al menos un elemento en la colección. Internamente este método itera sobre la colección retornando true
cuando encuentra el primer elemento, por lo que es mucho más eficiente que el anterior:var prods = services.GetProductsByCategory(category);
if (prods.Any()) // Mucho mejor :-)
{
// Hacer algo con los elementos de la lista
}
else
{
// No hay elementos
}
La utilización de
Any()
también es interesante para comprobar la existencia de elementos que cumplan una condición, expresada en forma de predicado; retornará true
cuando encuentre el primer elemento que lo haga cierto:if (pedidos.Any(p => p.Pendiente))
{
// Mostrar alerta, hay al menos un pedido pendiente
}Estamos en la puerta de un Estadio y queremos saber si vamos a ser los primeros en entrar al recinto… ¿le preguntaríamos al portero el número exacto de aficionados que ya están dentro para, si es cero, saber que somos los primeros? ¿O nos bastaría simplemente con preguntarle si hay alguien? ;-P
Publicado en: Variable not found
Hey: ¡estoy en Twitter!
Publicado por José M. Aguilar a las 12:01 a. m.
Etiquetas: .net, buenas prácticas, c#, desarrollo, linq, trucos, vb.net
public static class Helpers
{
public static string Image(this HtmlHelper helper, string src, string alt)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes["src"] = src;
tb.Attributes["alt"] = alt;
return tb.ToString(TagRenderMode.SelfClosing);
}
}
Que podía ser utilizado desde una vista de la siguiente forma, enviándolo al cliente con un bloque de salida directa de texto:
<%= Html.Image("/img/logo.gif", "Logo") %>
Hasta aquí todo correcto. Ahora, ASP.NET 4 ha introducido un nuevo bloque de salida de texto capaz de codificar automáticamente en HTML, lo cual ayuda a evitar ataques relacionados con la inyección de scripts:
// Lo que antes (ASP.NET < 4) era...
<%= Html.Encode(Model.FirstName) %>
// En ASP.NET 4 es:
<%: Model.FirstName %>
El nuevo bloque de salida codificada es el método aconsejado para emitir contenido al cliente y se espera que los desarrolladores vayamos acostumbrándonos progresivamente a utilizarlo siempre, dejando a un lado al
Esto tiene un efecto lateral no deseado cuando estamos utilizando helpers que generen HTML. Por ejemplo, si emitimos la salida del helper anterior utilizando esta nueva técnica, observad el resultado que obtendremos:
// En la vista Index.aspx:
<%: Html.Image("/img/logo.gif", "Logo") %>
MvcHtmlString
, introducida en ASP.NET MVC 2, que indica explícitamente a ASP.NET que no debe codificar la salida pues se trata de una cadena HTML controlada.Así, modificando el código del helper de la siguiente forma, obtendremos el resultado esperado:
public static class Helpers
{
public static MvcHtmlString Image(this HtmlHelper helper, string src, string alt)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes["src"] = src;
tb.Attributes["alt"] = alt;
return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
}
}
Todos los helpers del framework MVC destinados a generar marcado retornan ahora, en la versión 2, este nuevo tipo de datos, y esto es lo mismo que deberíamos hacer con nuestros helpers personalizados. Además, gracias a unos curiosos malabarismos realizados en el interior de
MvcHtmlString
, nuestros helpers funcionarán tanto con ASP.NET 3.5 SP1 como con ASP.NET 4, tanto si utilizamos salida codificada como si no.Publicado en: Variable not found.
Hey: ¡estoy en twitter!
Publicado por José M. Aguilar a las 11:45 p. m.
Etiquetas: asp.net, aspnetmvc, desarrollo, novedades
Espero que os resulten interesantes :-)
- ¿Qué ocurre con los parámetros opcionales de C# 4.0 cuando compilas para .NET 3.5?
Something you may not know is that Visual Studio 2010 will let you compile this against .NET 3.5, with no error or warning.
Fuente: weblogs.asp.net | Fecha: 16/04/2010 - Generar un feed RSS desde ASP.NET MVC con un ActionResult personalizado.
When building a website it is common to expose an RSS/ATOM feed for your content. Feeds serve two main purposes. The first, is that it allows other sites to consume your content for syndication. For example ...
Fuente: dotnet.dzone.com | Fecha: 16/04/2010 - Cómo enviar datos JSON a controladores MVC con jQuery.
This blog has personalition features for you, the reader. Below is a key of what all the icons mean and which aspects of the layout they change.
Fuente: lozanotek.com | Fecha: 16/04/2010 - ScottGu comenta el lanzamiento de Silverlight 4.
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 16/04/2010 - NoSQL con MongoDB, NoRM y ASP.NET MVC.
Shiju Varghese's Blog on ASP.NET MVC
Fuente: weblogs.asp.net | Fecha: 16/04/2010 - Hanselman comenta algunos breaking changes en ASP.NET 4 (= cosas con las que hay que tener cuidado).
Scott Hanselman on Programming, User Experience, The Zen of Computers and Life in General
Fuente: www.hanselman.com | Fecha: 13/04/2010 - Visual Studio 2010 en español será publicado en el mes de Mayo.
Fuente: twitter.com | Fecha: 13/04/2010 - ¿Por qué no existe un Visual Studio 2010 específico para 64 bits?
Disclaimer: This is yet another of my trademarked "approximately correct" discussions From time to time customers or partners ask me about our plans to create a 64 bit version of Visual Studio. When is it coming? Why aren’t we making it a priority? Haven’t
Fuente: blogs.msdn.com | Fecha: 13/04/2010 - Model Binding seguro y sencillo en ASP.NET MVC utilizando interfaces.
A little over a year ago (wow, it seems like only yesterday), I made a post called Think Before You Bind. In this post, I presented to you exactly why you want to make sure that when you are doing automatic ...
Fuente: www.codethinked.com | Fecha: 13/04/2010 - El día D: lanzado Visual Studio 2010 y NET 4.
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 13/04/2010 - Resumen de la evolución de C# hasta llegar a la versión actual.
.NET, Software Architecture
Fuente: weblogs.asp.net | Fecha: 12/04/2010 - Diez razones para utilizar Managed Extensibility Framework (MEF).
One question I'm commonly asked is, "Why do I need the Managed Extensibility Framework? How do I know when to use it?" In addition to that really being two questions, I'm not sure I can tell you the top ten reasons to use MEF or whether or not it is the right tool for you. ...
Fuente: csharperimage.jeremylikness.com | Fecha: 12/04/2010 - Precisión y exactitud de DateTime, o por qué debemos utilizar la clase StopWatch para cronometrar intervalos de tiempo.
The DateTime struct represents dates as a 64 bit number that measures the number of “ticks” since a particular start date. Ten million ticks equals one second.
Fuente: blogs.msdn.com | Fecha: 12/04/2010
Y no olvides que, si te interesa, puedes seguir esta información en vivo y en directo desde Variable not found en Facebook, o a través de Twitter.
Publicado en: Variable not found