<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10spanishfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0ENQn48fSp7ImA9WhRbGE8.&quot;"><id>tag:blogger.com,1999:blog-27752126</id><updated>2012-02-09T23:14:53.075+01:00</updated><category term="flash" /><category term="navidad" /><category term="2009" /><category term="vacaciones" /><category term="historias" /><category term="cadenas de conexión" /><category term="vs2008" /><category term="interfaces" /><category term="analytics" /><category term="signalr" /><category term="calidad" /><category term="curiosidades" /><category term="arquitectura" /><category term="opinión" /><category term="bytecode" /><category term="reflexiones" /><category term="webgrid" /><category term="spam" /><category term="inocentadas" /><category term="haloscan" /><category term="validadores" /><category term="eswebcamp" /><category term="xhtml" /><category term="errores" /><category term="connection strings" /><category term="antipatrones" /><category term="leyes" /><category term="scripting" /><category term="linq" /><category term="nupack" /><category term="paranoias" /><category term="xVal" /><category term="java" /><category term="árboles de expresión" /><category term="azure" /><category term="aniversario" /><category term="optimización" /><category term="liame" /><category term="niftydotnet" /><category term="rest" /><category term="nivel básico" /><category term="curso" /><category term="1337" /><category term="nivel medio" /><category term="proyectos" /><category term="nivel alto" /><category term="estándares" /><category term="2.0" /><category term="dsl" /><category term="viajes" /><category term="asp.net" /><category term="patrones" /><category term="blogging" /><category term="error" /><category term="dans" /><category term="depuración" /><category term="google" /><category term="trabajo" /><category term="ensamblador" /><category term="fluent interfaces" /><category term="technorati" /><category term="webpages" /><category term="chuletas" /><category term="navegadores" /><category term="msdewey" /><category term="delegados" /><category term="emoticonos" /><category term="epónimos" /><category term="aspnetmvc" /><category term="escaneo de puertos" /><category term="mvp" /><category term="productos" /><category term="envidia" /><category term="buenas prácticas" /><category term="Spectrum" /><category term="frameworks" /><category term="frases célebres" /><category term="servicios on-line" /><category term="equipos" /><category term="planetas" /><category term="redes" /><category term="troyanos" /><category term="vs" /><category term="técnicas de spam" /><category term="lambdas" /><category term="antispam" /><category term="silverlight" /><category term="chacha" /><category term="entrevistas" /><category term="leet speak" /><category term="ie" /><category term="charlas" /><category term="desarollo" /><category term="jqGrid" /><category term="jquery" /><category term="historia" /><category term="phishing" /><category term="ado.net" /><category term="scrum" /><category term="homenaje" /><category term="problema" /><category term="virus" /><category term="entity framework" /><category term="webmatrix" /><category term="conquista del mundo" /><category term="consultas" /><category term="nostalgia" /><category term="software libre" /><category term="ayuda" /><category term="web" /><category term="seguridad" /><category term="rendimiento" /><category term="desarrollo" /><category term="redes sociales" /><category term="interacción" /><category term="c#" /><category term="desastres" /><category term="css" /><category term="libros" /><category term="portales" /><category term="cultura" /><category term="creatividad" /><category term=".net" /><category term="diseño" /><category term="visualstudio" /><category term="vb.net" /><category term="humor" /><category term="métodos anónimos" /><category term="productividad" /><category term="emuladores" /><category term="motores de física" /><category term="bases de datos" /><category term="auges" /><category term="interfaces fluidos" /><category term="webforms" /><category term="t4" /><category term="análisis" /><category term="frikadas" /><category term="programación" /><category term="componentes" /><category term="software" /><category term="html" /><category term="utilidades" /><category term="riqueza" /><category term="cartujadotnet" /><category term="comentarios" /><category term="msil" /><category term="enlaces" /><category term="javascript" /><category term="autobombo" /><category term="localizacion" /><category term="communityday" /><category term="redondear esquinas" /><category term="óscar" /><category term="trucos" /><category term="innovadores" /><category term="cms" /><category term="vs2010" /><category term="tecnología" /><category term="instalación" /><category term="resumen" /><category term="glimpse" /><category term="ttt" /><category term="vs2005" /><category term="recomendaciones" /><category term="linux" /><category term="office" /><category term="personal" /><category term="ajax" /><category term="empresa" /><category term="genios" /><category term="herramientas" /><category term="protocolos" /><category term="colaboraciones" /><category term="variablenotfound.com" /><category term="tags" /><category term="blogger" /><category term="SEO" /><category term="buscadores" /><category term="noticias" /><category term="novedades" /><category term="ofuscación de emails" /><category term="orcas" /><category term="orm" /><category term="razor" /><category term="eventos" /><category term="microsoft" /><category term="quaere" /><category term="actualidad" /><category term="mono" /><category term="alegrías" /><category term="data" /><category term="fiddler" /><title>Variable not found</title><subtitle type="html">Artículos, noticias, curiosidades, reflexiones... sobre el mundo del desarrollo de software, internet, u otros temas relacionados con la tecnología.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.variablenotfound.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>496</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/vnf" /><feedburner:info uri="vnf" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>vnf</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fvnf" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/vnf" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fvnf" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fvnf" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fvnf" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://add.my.yahoo.com/content?lg=es&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fvnf" src="http://eur.i1.yimg.com/eur.yimg.com/i/es/my/addto1.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.feedness.com/alta/http://feeds.feedburner.com/vnf" src="http://www.feedness.com/ayuda/wp-content/square_b_sh_feed.gif">Subscribe with Feedness</feedburner:feedFlare><entry gd:etag="W/&quot;DUAHRns7fip7ImA9WhRbFkU.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-3699698385345734546</id><published>2012-02-08T08:55:00.000+01:00</published><updated>2012-02-08T08:55:37.506+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-08T08:55:37.506+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="curiosidades" /><category scheme="http://www.blogger.com/atom/ns#" term="humor" /><category scheme="http://www.blogger.com/atom/ns#" term="frikadas" /><title>Llamemos a las cosas por su nombre</title><content type="html">&lt;img align="right" alt="Errores y usuarios" border="0" height="121" src="http://lh5.ggpht.com/-WMp2F0keaqQ/Tpas-dDFBTI/AAAAAAAABoo/SjMl17h6hWk/image3.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Errores y usuarios" width="184" /&gt;Seguro que todos sabéis lo que es &lt;strong&gt;tratar con los usuarios de vuestro software&lt;/strong&gt;: son lentos, patosos, inconscientes, atrevidos, inseguros, ignorantes, y no consiguen entender la belleza de la herramienta que con tanto esmero hemos creado. Y lo que más rabia da es que &lt;strong&gt;muchas veces tienen razón&lt;/strong&gt; en los problemas que reportan de nuestras aplicaciones. &lt;br /&gt;
&lt;br /&gt;
Pero afortunadamente &lt;strong&gt;otras veces no es así, y los problemas no son nuestros sino suyos&lt;/strong&gt;, momento en el que pone a disposición de la dulce venganza la genial creatividad característica de nuestro gremio.&lt;br /&gt;
&lt;br /&gt;
Lo que vamos a ver a continuación son siete de las formas existentes, conocidas y documentadas de cargar las culpas sobre el usuario, o simplemente llamarlo torpe, sin que éste se dé cuenta. Algo muy socorrido si, por ejemplo, debemos contarle a un compañero lo que ocurre en presencia del implicado.&lt;br /&gt;
&lt;br /&gt;
Por supuesto, a partir de aquí todo es secreto, no dejéis que caiga en manos de algún desalmado ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;h4&gt;


1. Error ID-10-T&lt;/h4&gt;
El "ID-10-T" (pronunciado &lt;em&gt;ID-ten-T&lt;/em&gt;) es un código de error que se utiliza para &lt;strong&gt;indicar que el usuario es simplemente idiota&lt;/strong&gt;. De hecho, si unimos las letras (ID10T) podremos ver fácilmente que el término es la traducción a &lt;a href="http://www.variablenotfound.com/2009/01/sabes-1337.html"&gt;leet speak&lt;/a&gt; de IDIOT, lo cual no podía dejar más clara su intencionalidad y los momentos en que debemos utilizarlo.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/User_error#ID-10-T_Error"&gt;Se rumorea&lt;/a&gt; que en los años noventa los equipos de soporte técnico telefónico daban instrucciones a los usuarios y clientes para que incluyeran en su archivo &lt;em&gt;config.sys&lt;/em&gt; la línea &lt;code&gt;id=10t&lt;/code&gt; (o combinaciones parecidas) como aviso para futuras intervenciones cuando se encontraban con un espécimen a tener en cuenta.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ars.userfriendly.org/cartoons/?id=19990211"&gt;&lt;img alt="ID10T" border="0" height="238" src="http://lh3.ggpht.com/-kubjFUvv7IE/Tpas_EdUDXI/AAAAAAAABow/ld8ymF6obzY/image10.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ID10T" width="626" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
También podemos encontrarlo, aunque en menor medida, escrito como ID107, otra posible traducción del término al lenguaje &lt;a href="http://www.variablenotfound.com/2009/01/sabes-1337.html"&gt;1337&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Curiosamente, el término se utiliza en otros ámbitos como el militar, aunque la pronunciación puede variar ligeramente:&amp;nbsp; &lt;em&gt;“One delta ten tango”&lt;/em&gt; o &lt;em&gt;“Eye Dee Ten Tango”&lt;/em&gt;.&lt;br /&gt;
&lt;h4&gt;


2. Wetware bugs&lt;/h4&gt;
Tradicionalmente, los errores en sistema informáticos podían producirse bien en el hardware, la parte física, o bien en el software, la parte lógica. Pues en contraposición a éstos, el Wetware, &lt;b&gt;hace referencia a la “parte blanda”&lt;/b&gt;, es decir, al individuo que los utiliza y, más en concreto, a su mente.&lt;br /&gt;
&lt;br /&gt;
De esta forma, el eufemismo “fallo en el Wetware” es sólo una fórmula políticamente correcta de indicar un problema causado por el usuario, o un problema del usuario en sí ;-)&lt;br /&gt;
&lt;br /&gt;
Se pueden encontrar variantes relativas al mismo concepto, como Liveware (utilizado por primera vez en 1966!) o Meatware, ambos con el mismo significado.&lt;br /&gt;
&lt;h4&gt;


3. PEBCAK&lt;/h4&gt;
Este término, todo un clásico entre el personal de soporte de sistemas, es un acrónimo de:&lt;br /&gt;
&lt;blockquote&gt;
&lt;strong&gt;Problem Exists Between Chair And Keyboard &lt;/strong&gt;      &lt;br /&gt;
(el problema existe entre la silla y el teclado)&lt;/blockquote&gt;
Por tanto, se trata de una forma indescifrable de indicar que un problema está provocado exclusivamente por el usuario que está manejando el sistema.&lt;br /&gt;
&lt;br /&gt;
Existen bastantes variaciones de este término, que combinan algunos verbos con ordenadores, teclados, monitores y sillas:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;EBKAC (Error Between Keyboard And Chair) &lt;/li&gt;
&lt;li&gt;PIBCAK (Problem Is Between Chair And Keyboard) &lt;/li&gt;
&lt;li&gt;PIBKAC (Problem Is Between Keyboard And Chair) &lt;/li&gt;
&lt;li&gt;PLBKAC (Problem Lies Between Keyboard And Chair) &lt;/li&gt;
&lt;li&gt;POBCAC (Problem Occurs Between Computer And Chair) &lt;/li&gt;
&lt;li&gt;PEBCAC (Problem Exists Between Chair And Computer) &lt;/li&gt;
&lt;li&gt;PEBMAC (Problem Exists Between Monitor And Chair) &lt;/li&gt;
&lt;li&gt;PEBKAM (Problem Exists Between Keyboard and Monitor) &lt;/li&gt;
&lt;/ul&gt;
&lt;a href="http://ars.userfriendly.org/cartoons/?id=19980506"&gt;&lt;img alt="PEBKAC" border="0" height="238" src="http://lh5.ggpht.com/-JV6_pUh449E/Tpas_4bDkyI/AAAAAAAABo4/cWXqnqsEVio/image4.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="PEBKAC" width="626" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;


4. PICNIC&lt;/h4&gt;
&lt;a href="http://www.spreadshirt.co.uk/black-problem-in-chair-not-in-computer-C4408A6852154"&gt;&lt;img align="right" alt="PICNIC - Problem in chair, not in computer" border="0" height="156" src="http://lh4.ggpht.com/-1dOswkjFXZc/TpatAdGYqwI/AAAAAAAABpA/bTJo7eAy_QI/image9.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="PICNIC - Problem in chair, not in computer" width="150" /&gt;&lt;/a&gt;Otro acrónimo clásico, bastante más fácil de pronunciar que los anteriores, y que de la misma forma carga las culpas en el usuario del sistema:&lt;br /&gt;
&lt;blockquote&gt;
&lt;strong&gt;Problem In Chair, Not In Computer &lt;/strong&gt;      &lt;br /&gt;
(el problema está en la silla, no en el ordenador)       &lt;/blockquote&gt;
Y no, no tiene nada que ver con la ergonomía del mobiliario: el “en” hace referencia a la segunda acepción que la RAE que da a esta preposición, y significa “&lt;a href="http://buscon.rae.es/draeI/SrvltConsulta?TIPO_BUS=3&amp;amp;LEMA=en"&gt;sobre&lt;/a&gt;” ;-)&lt;br /&gt;
&lt;br /&gt;
Este término puede ser pronunciado sin temor a duchar a nuestro interlocutor, es bastante sencillo de recordar, e incluso de utilizar con absoluta impunidad ante el propio protagonista sin temor a levantar sospechas (“estamos ante un caso picnic”).&lt;br /&gt;
&lt;img align="right" alt="La pila OSI extendida. Basado en diagrama de Wikipedia." border="0" height="305" src="http://lh6.ggpht.com/-DPBAeWqk2BI/TpatAzkgvNI/AAAAAAAABpI/TrGIjxMtMXU/image25.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="La pila OSI extendida. Basado en diagrama de Wikipedia." width="165" /&gt;&lt;br /&gt;
&lt;h4&gt;


5. Layer 8 error&lt;/h4&gt;
En el año 1984, la &lt;a href="http://es.wikipedia.org/wiki/Organizaci%C3%B3n_Internacional_para_la_Estandarizaci%C3%B3n" title="Organización Internacional para la Estandarización"&gt;Organización Internacional para la Estandarización&lt;/a&gt; publicó un modelo de referencia para la definición de arquitecturas de sistemas de comunicación llamado &lt;a href="http://es.wikipedia.org/wiki/Modelo_OSI"&gt;OSI&lt;/a&gt; (&lt;em&gt;Open System Interconnection&lt;/em&gt;). &lt;br /&gt;
&lt;br /&gt;
Este modelo conceptualizaba los componentes y sistemas involucrados en comunicaciones en base a distintos niveles: el nivel físico, el de enlace, de red, transporte, sesión, presentación y aplicación. Un total de &lt;strong&gt;siete capas&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
¿Adivináis ya qué es el nivel 8, verdad? ;-D&lt;br /&gt;
&lt;br /&gt;
Pues efectivamente. Se trata de una forma jocosa de llamar al usuario o al factor humano entre los administradores de redes, como parte imprescindible para el correcto funcionamiento de los sistemas interconectados. Si hay problemas o errores en el Layer 8, no importa lo que ocurra en el resto de niveles: simplemente las cosas no funcionan.&lt;br /&gt;
&lt;br /&gt;
También suele utilizarse el término para referirse a aspectos económicos e incluso políticos cuyos intereses pueden afectar igualmente&amp;nbsp;al funcionamiento de los sistemas.&lt;br /&gt;
&lt;h4&gt;


6. RTFM&lt;/h4&gt;
Este término no alude directamente a la falta de habilidad del usuario, sino a su desconocimiento de aspectos que se recogen en documentación existente que deberían haber leído. Las siglas corresponden a la expresión:&lt;br /&gt;
&lt;blockquote&gt;
&lt;strong&gt;Read The&amp;nbsp; Fucking Manual&lt;/strong&gt;       &lt;br /&gt;
(Lee el jodido manual)       &lt;/blockquote&gt;
&lt;a href="http://xkcd.com/293/"&gt;&lt;img align="right" alt="RTFM!" border="0" height="269" src="http://lh5.ggpht.com/-P49M2lYcv58/TpatBYUpz2I/AAAAAAAABpQ/G1_wZim7hXw/image32.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="RTFM!" width="217" /&gt;&lt;/a&gt;Y es que no hay nada más desagradecido que trabajar durante varios días o semanas en un completo manual de usuario y recibir preguntas sobre temas que vienen perfectamente detallados en éste. ¿Es que ni siquiera se molestan en leerlo?&lt;br /&gt;
&lt;br /&gt;
Bueno, si queréis podemos responder ya a la pregunta: no. Ni de coña. Pero el que esté libre de pecado que tire la primera piedra… ¿cuándo fue la última vez que te leíste un manual? El de Windows 7, ¿lo has terminado ya? ¿Y el de Visual Studio? ¿El de la impresora, tal vez? ;-P&lt;br /&gt;
&lt;br /&gt;
Existe una segunda interpretación de RTFM, aunque menos usada: “&lt;strong&gt;Reboot The Fucking Machine&lt;/strong&gt;” (reinicia la jodida máquina), que podría ser útil para identificar las soluciones “apaga y enciende” tan populares en los 90 y primer lustro del 2000.&lt;br /&gt;
&lt;h4&gt;


7. Luser&lt;/h4&gt;
En este caso tenemos un &lt;a href="http://en.wikipedia.org/wiki/Portmanteau"&gt;portmanteau&lt;/a&gt; o contracción entre las palabras &lt;em&gt;&lt;strong&gt;User&lt;/strong&gt;&lt;/em&gt; (usuario) y&amp;nbsp; &lt;em&gt;&lt;strong&gt;Loser&lt;/strong&gt;&lt;/em&gt; (perdedor, fracasado) utilizado frecuentemente para referirse a la gente cuyos conocimientos informáticos rozan el cero absoluto, y que tanto suelen irritar a los expertos, hackers y demás fauna binaria.&lt;br /&gt;
&lt;a href="http://www.tecnolack.com/comico/humor-geek-mirar-a-un-luser-usando-la-computadora/"&gt;&lt;img align="right" alt="Mirar un luser usando el ordenador" border="0" height="160" src="http://lh5.ggpht.com/-N6tWSkoQViU/TpatB_CLiUI/AAAAAAAABpY/pICPwmwbNbg/image37.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Mirar un luser usando el ordenador" width="333" /&gt;&lt;/a&gt;&lt;br /&gt;
El origen del término se remonta al año 1975, en el MIT, donde algún bromista pensó que sería simpático que los comandos para consultar el número de usuarios conectados los llamara &lt;em&gt;losers&lt;/em&gt; en lugar de &lt;em&gt;users&amp;nbsp;&lt;/em&gt;(por ejemplo: “&lt;em&gt;8 losers&lt;/em&gt;” en vez de “&lt;em&gt;8 users&lt;/em&gt;”) y lo introdujo en el sistema ITS que manejaban. Dado que la idea no gustó mucho al resto de usuarios, fue evolucionando hasta encontrar el término &lt;em&gt;lusers&lt;/em&gt;, políticamente más correcto y compatible con “&lt;em&gt;logged users&lt;/em&gt;”.&lt;br /&gt;
&lt;br /&gt;
Es habitual encontrar &lt;em&gt;lusers&lt;/em&gt; preguntando cosas bastante simples, incluso absurdas, en foros y otras redes sociales. Normalmente las respuestas a sus cuestiones podrían resolverlas por ellos mismos sólo con un poco de interés, pero prefiere preguntar por comodidad. Y especialmente grave es cuando coincide además que el usuario es un &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Leech_(computing)"&gt;leech&lt;/a&gt;&lt;/em&gt; (sanguijuela), es decir, alguien que no agradece ni aporta nada a quienes dedican su tiempo a ayudarle.&lt;br /&gt;
&lt;br /&gt;
Como antídotos, destacan los famosos &lt;a href="http://lmgtfy.com/?q=luser"&gt;LMGTFY (Let me Google that for you)&lt;/a&gt; –con versión en español-, o la alternativa &lt;a href="http://letmebingthatforyou.com/?q=luser"&gt;LMBTFY (Let me Bing that for you)&lt;/a&gt;, ambos una forma muy elegante de decirle lo que piensas realmente de él y sus preguntas.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;¿Y tú, cómo llamas a tus usuarios?&lt;/strong&gt;&lt;br /&gt;
________________________________________&lt;br /&gt;
Fuentes utilizadas: &lt;a href="http://en.wikipedia.org/"&gt;Wikipedia&lt;/a&gt;, &lt;a href="http://en.wiktionary.org/"&gt;Wiktionary&lt;/a&gt;, &lt;a href="http://www.retrologic.com/jargon/"&gt;The Jargon file&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-3699698385345734546?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pcs2uCD5MQlk-4Of5_-fZoB3QQg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pcs2uCD5MQlk-4Of5_-fZoB3QQg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pcs2uCD5MQlk-4Of5_-fZoB3QQg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pcs2uCD5MQlk-4Of5_-fZoB3QQg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Dz6XK9PpQVA:-T0XhcN9hOs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Dz6XK9PpQVA:-T0XhcN9hOs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Dz6XK9PpQVA:-T0XhcN9hOs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Dz6XK9PpQVA:-T0XhcN9hOs:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/Dz6XK9PpQVA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/3699698385345734546/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=3699698385345734546" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3699698385345734546?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3699698385345734546?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/Dz6XK9PpQVA/llamemos-las-cosas-por-su-nombre.html" title="Llamemos a las cosas por su nombre" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-WMp2F0keaqQ/Tpas-dDFBTI/AAAAAAAABoo/SjMl17h6hWk/s72-c/image3.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/02/llamemos-las-cosas-por-su-nombre.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMFQHkzfyp7ImA9WhRbFU8.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-7793668128724219846</id><published>2012-02-06T11:00:00.000+01:00</published><updated>2012-02-06T11:00:11.787+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-06T11:00:11.787+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 70</title><content type="html">&lt;a href="http://lh5.ggpht.com/-3taOarDdaz4/Ty7eQHXq6lI/AAAAAAAABwE/-k-svJRmox0/s1600-h/image7_thumb_thumb_thumb_thumb_thumb.png"&gt;&lt;img align="right" alt="Enlaces interesantes" border="0" height="129" src="http://lh3.ggpht.com/-ha0IzYUlLao/Ty7eQ8x9K8I/AAAAAAAABwM/-ACMFNFIIjo/image7_thumb_thumb_thumb_thumb_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes" width="172" /&gt;&lt;/a&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 31 de enero al 5 de febrero de 2012. Espero que os resulten interesantes :-)&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;


.Net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2012/Feb/01/Dynamic-Types-and-DynamicObject-References-in-C"&gt;&lt;strong&gt;Dynamic Types and DynamicObject References in C#&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Rick Strahl       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://visualstudiomagazine.com/articles/2012/02/01/simplify-your-projections-with-automapper.aspx"&gt;Simplify Your Projections with AutoMapper&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Patrick Steele &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.emgu.com/wiki/index.php/Face_detection"&gt;Face detection in C# with Emgu&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Emgu &lt;/li&gt;
&lt;li&gt;&lt;a href="http://haacked.com/archive/2012/01/29/hazards-of-converting-binary-data-to-a-string.aspx"&gt;&lt;strong&gt;Hazards of Converting Binary Data To A String&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Phil Haack &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.stefanprodan.eu/2012/01/user-friendly-captcha-for-asp-net-mvc/"&gt;&lt;strong&gt;User friendly CAPTCHA for Asp.Net MVC&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Stefan Prodan &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blackrabbitcoder.net/archive/2012/01/26/c.net-little-pitfalls-implicit-zero-to-enum-conversion.aspx"&gt;&lt;strong&gt;C#/.NET Little Pitfalls: Implicit Zero To Enum Conversion&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;James Michael Hare &lt;/li&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/ul&gt;
&lt;h4&gt;


Asp.net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeproject.com/Articles/320219/Lucene-Net-ultra-fast-search-for-MVC-or-WebForms"&gt;Lucene.Net ultra fast search for MVC or WebForms site =&amp;gt; made easy!&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Mikhail T. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.dotnetnuke.com/Resources/Blogs/EntryId/3275/ASP-Net-WebForms-and-MVC-are-Dead-to-Me.aspx"&gt;&lt;strong&gt;ASP.Net WebForms and MVC are Dead to Me&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Joe Brinkman &lt;/li&gt;
&lt;li&gt;Creating a Bilingual ASP.NET MVC 3 Application, &lt;a href="http://www.codeproject.com/Articles/181738/Creating-a-Bilingual-ASP-NET-MVC3-Application-Part"&gt;&lt;strong&gt;part I&lt;/strong&gt;&lt;/a&gt; and &lt;strong&gt;&lt;a href="http://www.codeproject.com/Articles/207602/Creating-a-Bilingual-ASP-NET-MVC3-Application-Part"&gt;part II&lt;/a&gt;&lt;/strong&gt;.       &lt;br /&gt;Keith Barrow &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://reddevnews.com/blogs/rdn-express/2012/01/go-live-license-planned-for-asp.net-mvc-4-pre-release.aspx"&gt;Go Live License Planned for ASP.NET MVC 4 Pre-Release&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Kathleen Richards &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hanselman.com/blog/OneASPNETSneakPeekElegantWebFormsAndSnowballsInHell.aspx"&gt;&lt;strong&gt;One ASP.NET Sneak Peek: Elegant Web Forms and Snowballs in Hell&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Scott Hanselman       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://umbraco.com/follow-us/blog-archive/2012/1/31/umbraco-50-rtm-is-on-codeplex,-ready-for-download.aspx"&gt;Umbraco 5.0 RTM is on CodePlex, ready for download&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;small&gt;Alex Norcliffe&lt;/small&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=785"&gt;Tag Cloud in ASP.NET MVC using Clickable HTML 5 Canvas Elements&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Sumit Maitra       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-Dynamic-Model-Binding.aspx"&gt;ASP.NET MVC Dynamic Model Binding&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jing Ding &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;


Data access&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/02/01/orapoco-v2-0.aspx"&gt;ORAPOCO: V2.0&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Javier Torrecilla &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://elegantcode.com/2012/01/26/sqlbulkcopy-for-generic-listt-useful-for-entity-framework-nhibernate/"&gt;SqlBulkCopy for Generic List&amp;lt;T&amp;gt; (useful for Entity Framework &amp;amp; NHibernate)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jarod Ferguson &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2012/01/30/ddd-agregados-y-nosql.aspx"&gt;DDD, agregados y NoSQL&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Unai Zorrilla &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;


Html/Css/Javascript&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://webdemo.visionobjects.com/portal.html?locale=es_ES"&gt;Componentes para reconocimiento de escritura manuscrita con javascript&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Vision objects &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://css-tricks.com/star-ratings/"&gt;Star Ratings With Very Little CSS&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Chris Coyier       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.jquery4u.com/plugins/10-worth-checking-jquery-plugins/"&gt;10 Worth Checking Out jQuery Plugins&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;jQuery4u &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.paulund.co.uk/how-to-create-a-simple-modal-box-with-jquery"&gt;How To Create A Simple Modal Box With JQuery&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Paulund &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://lostechies.com/derickbailey/2012/01/27/dont-rely-solely-on-jquerys-keyup-event/"&gt;Don’t Rely Solely On jQuery’s “keyup” Event&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Derick Bailey &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.kirupa.com/html5/naming_via_class_id_name.htm"&gt;Naming via Class, ID, and Name&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Kirupa Chinnathambi &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Elijah Manor &lt;/li&gt;
&lt;li&gt;&lt;a href="http://hacks.mozilla.org/2012/01/hidden-gems-of-html5-classlist/"&gt;&lt;strong&gt;Hidden Gems of HTML5: classList&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Chris Heilmann &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/gperez/archive/2012/01/31/introducci-243-n-a-linq-to-javascript.aspx"&gt;Introducción a Linq to JavaScript&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gonzalo Pérez &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;


Visual Studio/Complementos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/elbruno/archive/2012/02/03/resharper-howto-convertir-string-string-en-string-format.aspx" title="http://geeks.ms/blogs/elbruno/archive/2012/02/03/resharper-howto-convertir-string-string-en-string-format.aspx"&gt;&lt;strong&gt;[#RESHARPER] HowTo: Convertir string + string en string.format()&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Bruno Capuano &lt;/li&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/ul&gt;
&lt;h4&gt;


Otros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://speakingin.net/2012/02/01/cell%c2%b7sdk-el-mismo-codigo-en-windows-phone-ios-y-android/"&gt;&lt;strong&gt;Cell·SDK: El mismo código en Windows Phone, iOS y Android&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Juan María Laó &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/dohollan/archive/2012/02/01/kinect-for-windows-released-today.aspx"&gt;KINECT for Windows Released Today!!!&lt;/a&gt;         &lt;/strong&gt;Doug Holland &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://msmvps.com/blogs/peterritchie/archive/2012/01/30/what-code-comments-are-not-for.aspx"&gt;What Code Comments are Not For&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Peter Ritchie &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-7793668128724219846?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PnvlrxF29iFPizmDfvVJL0GUY5s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PnvlrxF29iFPizmDfvVJL0GUY5s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PnvlrxF29iFPizmDfvVJL0GUY5s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PnvlrxF29iFPizmDfvVJL0GUY5s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=tXjClfMxdYU:OvB8YYHIF_A:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=tXjClfMxdYU:OvB8YYHIF_A:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=tXjClfMxdYU:OvB8YYHIF_A:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tXjClfMxdYU:OvB8YYHIF_A:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/tXjClfMxdYU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/7793668128724219846/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=7793668128724219846" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7793668128724219846?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7793668128724219846?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/tXjClfMxdYU/enlaces-interesantes-70.html" title="Enlaces interesantes 70" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-ha0IzYUlLao/Ty7eQ8x9K8I/AAAAAAAABwM/-ACMFNFIIjo/s72-c/image7_thumb_thumb_thumb_thumb_thumb%25255B1%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/02/enlaces-interesantes-70.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEHQnk4fCp7ImA9WhRbFE4.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-4075930113289782465</id><published>2012-02-01T11:47:00.000+01:00</published><updated>2012-02-05T11:10:33.734+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-05T11:10:33.734+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="validadores" /><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="trucos" /><title>Validación manual con Data Annotations</title><content type="html">&lt;img align="right" alt="Microsoft .NET" border="0" height="50" src="http://lh5.ggpht.com/-y33LGS5zgnE/Tv8yaqnLUTI/AAAAAAAABts/TPejSo7Odpo/image%25255B2%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Microsoft .NET" width="199" /&gt; Habitualmente asociamos la validación de entidades basadas en anotaciones de datos, o &lt;em&gt;data annotations&lt;/em&gt;, a tecnologías como &lt;em&gt;dynamic data&lt;/em&gt; o ASP.NET MVC, y estamos acostumbrados a que la validación se realice de forma automática, pero nada más lejos de la realidad. &lt;strong&gt;Podemos utilizar &lt;em&gt;data annotations&lt;/em&gt; desde cualquier tipo de aplicación .NET&lt;/strong&gt; (Webforms, Winforms, WPF, Consola, o cualquier otra en la que tengamos disponible &lt;span style="font-family: Courier New;"&gt;System.ComponentModel.DataAnnotations&lt;/span&gt;), puesto que existe la posibilidad de invocar manualmente los procedimientos de validación.&lt;br /&gt;
&lt;br /&gt;
En este post vamos a ver &lt;strong&gt;cómo realizar validaciones basadas en anotaciones de forma manual&lt;/strong&gt;, lo cual puede tener su utilidad en gran número de escenarios.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Resumidamente, esta técnica consiste en decorar cada una de las propiedades con una serie de atributos llamados anotaciones (definidos en &lt;code&gt;System.ComponentModel.DataAnnotations&lt;/code&gt;)&amp;nbsp; que indican las comprobaciones que se aplicarán a la entidad para determinar su validez. La siguiente porción de código muestra una entidad en la que se están indicando estas restricciones en cada una de sus propiedades:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;StringLength(&lt;span style="color: black;"&gt;50&lt;/span&gt;)&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Range&lt;/span&gt;(0, 120)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; Age { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
En el citado espacio de nombres encontramos &lt;strong&gt;atributos que cubren la mayoría de casos&lt;/strong&gt; frecuentes: &lt;code&gt;Required&lt;/code&gt; (propiedad obligatoria), &lt;code&gt;RegularExpression&lt;/code&gt; (validar contra una expresión regular), &lt;code&gt;StringLength (&lt;/code&gt;longitud máxima y mínima de un texto), &lt;code&gt;Range&lt;/code&gt; (rangos de valores permitidos), y &lt;code&gt;CustomValidation&lt;/code&gt; (validaciones personalizadas). Además, este conjunto de anotaciones puede ser extendido muy fácilmente creando atributos que hereden de &lt;code&gt;ValidationAttribute&lt;/code&gt;, disponible también en &lt;code&gt;System.ComponentModel.DataAnnotations&lt;/code&gt;.&lt;br /&gt;
&lt;h3&gt;


       Validación manual de objetos&lt;/h3&gt;
De lo más sencillo: la clase estática &lt;code&gt;Validator&lt;/code&gt;, disponible también en el &lt;em&gt;namespace&lt;/em&gt; &lt;code&gt;System.ComponentModel.DataAnnotations&lt;/code&gt;, ofrece métodos que permiten realizar las comprobaciones de forma directa sobre objetos o propiedades concretas.&lt;br /&gt;
&lt;br /&gt;
En este caso, dado que lo que nos interesa es validar las entidades completas, utilizaremos el método &lt;code&gt;Validator.TryValidateObject()&lt;/code&gt;, al que suministraremos:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;el objeto a validar, &lt;/li&gt;
&lt;li&gt;un contexto de validación (que debemos crear previamente), &lt;/li&gt;
&lt;li&gt;una colección de &lt;code&gt;ValidationResult&lt;/code&gt; en la que almacenaremos los errores, &lt;/li&gt;
&lt;li&gt;y, por último, si deseamos validar todas las propiedades (indicando &lt;code&gt;true&lt;/code&gt;), o por el contrario preferimos parar el proceso en cuanto se detecte el primer error (&lt;code&gt;false&lt;/code&gt;). &lt;/li&gt;
&lt;/ul&gt;
La implementación de la validación podría ser como la que la sigue:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;ValidationResult&lt;/span&gt;&amp;gt; getValidationErrors(&lt;span style="color: blue;"&gt;object&lt;/span&gt; obj)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; validationResults = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;ValidationResult&lt;/span&gt;&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; context = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ValidationContext&lt;/span&gt;(obj, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: blue;"&gt;null&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Validator&lt;/span&gt;.TryValidateObject(obj, context, validationResults, &lt;span style="color: blue;"&gt;true&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; validationResults;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
El método retornará una lista de errores vacía cuando el objeto haya superado las restricciones impuestas, o llena con los objetos &lt;code&gt;ValidationResult&lt;/code&gt; que describen los problemas encontrados.&lt;br /&gt;
&lt;br /&gt;
Y podríamos utilizarlo desde una aplicación de consola de la siguiente forma:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; friend = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt; { Age = -1, Name = &lt;span style="color: #a31515;"&gt;""&lt;/span&gt; };
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; errors = getValidationErrors(friend);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; error &lt;span style="color: blue;"&gt;in&lt;/span&gt; errors)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;.WriteLine(error.ErrorMessage);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div style="background-color: black; color: white; font-family: consolas; font-size: 10pt; margin: 10px auto 10px 30px; padding: 3px;"&gt;
The Name field is required. &lt;br /&gt;
&lt;br /&gt;
The field Age must be between 0 and 120. &lt;/div&gt;
Los mensajes de validación que aparecen pueden ser definidos en la misma anotación, por ejemplo así:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;(ErrorMessage=&lt;span style="color: #a31515;"&gt;"Please, enter the name"&lt;/span&gt;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;


       ¿Y si los metadatos están en otra clase?&lt;/h3&gt;
&lt;strong&gt;Hay escenarios en los que no tenemos acceso a la clase&lt;/strong&gt; en la que deseamos introducir las anotaciones. Un ejemplo claro lo encontramos cuando nos interesa especificar las restricciones en una clase generada por un proceso automático, como el diseñador de EDM de Entity framework; cualquier cambio realizado sobre el código generado será sobrescrito sin piedad al modificar el modelo.&lt;br /&gt;
&lt;br /&gt;
En estos casos, &lt;strong&gt;es una práctica frecuente definir los metadatos en clases “buddy”&lt;/strong&gt;, que son copias exactas de la entidad a anotar, pero que serán utilizadas únicamente como contenedores de anotaciones. Las clases buddy se vinculan con la entidad original utilizando el atributo &lt;code&gt;&lt;a href="http://msdn.microsoft.com/es-es/library/system.componentmodel.dataannotations.metadatatypeattribute.aspx"&gt;MetadataType&lt;/a&gt;&lt;/code&gt; de la siguiente forma:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// This class has been generated by a tool&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;partial&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; Age { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Let's associate the buddy class FriendMetadata&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: yellow;"&gt;[&lt;span style="color: #2b91af;"&gt;MetadataType&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;FriendMetadata&lt;/span&gt;))]&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;partial&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Buddy class&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;FriendMetadata&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Range&lt;/span&gt;(0, 120)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; Age { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Observad que para poder utilizar esta técnica es necesario que la entidad a la que queremos añadir anotaciones sea creada como parcial. En caso contrario no podríamos indicarle con &lt;code&gt;MetadataType&lt;/code&gt; dónde se encuentran definidos sus atributos de validación.&lt;br /&gt;
&lt;br /&gt;
Pues bien, resulta que algunos marcos de trabajo (como ASP.NET MVC) están preparados para detectar este escenario y obtener de forma automática los metadatos desde la clase buddy, pero &lt;strong&gt;si estamos realizando la validación de forma manual el atributo &lt;code&gt;[MetadataType]&lt;/code&gt; no será tenido en cuenta&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
Por tanto, debemos ser nosotros los que indiquemos expresamente dónde se encuentran los metadatos, para lo que, afortunadamente, contamos con la ayuda de &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspx"&gt;&lt;code&gt;&lt;/code&gt;&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspx"&gt;TypeDescriptor&lt;/a&gt;&amp;nbsp; (definida en &lt;code&gt;System.ComponentModel&lt;/code&gt;), desde donde podemos indicar el origen de los metadatos de clases simplemente registrando el proveedor desde el cual pueden ser obtenidos.&lt;br /&gt;
&lt;br /&gt;
El procedimiento para conseguirlo es bastante simple: creamos un proveedor de descripciones basado en metadatos utilizando la clase &lt;a href="http://msdn.microsoft.com/es-es/library/system.componentmodel.dataannotations.associatedmetadatatypetypedescriptionprovider.aspx"&gt;AssociatedMetadataTypeTypeDescriptionProvider&lt;/a&gt;&lt;code&gt;&lt;/code&gt; (uuf con el nombrecito ;-)) en el que vinculamos la clase “original” con la que contiene los metadatos (la clase buddy), y a continuación añadimos dicho proveedor a la primera.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, para hacer que las anotaciones de la clase &lt;code&gt;Friend&lt;/code&gt; se obtengan desde el tipo &lt;code&gt;FriendMetadata&lt;/code&gt; podríamos incluir el siguiente código de inicialización:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;var&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt; descriptionProvider = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;AssociatedMetadataTypeTypeDescriptionProvider&lt;/span&gt;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;), 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;FriendMetadata&lt;/span&gt;)
);
&lt;span style="color: #2b91af;"&gt;TypeDescriptor&lt;/span&gt;.AddProviderTransparent(descriptionProvider, &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Otra posibilidad más genérica sería implementarlo como se muestra a continuación, donde buscamos en todo el ensamblado actual clases decoradas con el atributo &lt;code&gt;MetadataType&lt;/code&gt;, registrando el proveedor de metadatos indicado en dicho atributo de forma automática:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; registerBuddyClasses()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; buddyAssociations = 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;from&lt;/span&gt; t &lt;span style="color: blue;"&gt;in&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly().GetTypes()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; md = t.GetCustomAttributes(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;MetadataTypeAttribute&lt;/span&gt;), &lt;span style="color: blue;"&gt;false&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .FirstOrDefault() &lt;span style="color: blue;"&gt;as&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MetadataTypeAttribute&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;where&lt;/span&gt; md != &lt;span style="color: blue;"&gt;null&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt; { Type = t, Buddy = md.MetadataClassType };
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; association &lt;span style="color: blue;"&gt;in&lt;/span&gt; buddyAssociations)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; descriptionProvider = 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;AssociatedMetadataTypeTypeDescriptionProvider&lt;/span&gt;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; association.Type, association.Buddy
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;TypeDescriptor&lt;/span&gt;.AddProviderTransparent(descriptionProvider, association.Type);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
De esta forma, bastará con invocar el método &lt;code&gt;registerBuddyClasses()&lt;/code&gt; durante la inicialización de la aplicación para que las clases buddy sean registradas de forma automática.&lt;br /&gt;
&lt;br /&gt;
Pero más interesante es, sin duda, que &lt;strong&gt;podríamos implementar nuevas fórmulas para indicar dónde se encuentran los metadatos&lt;/strong&gt; de una clase. Por ejemplo, sería realmente sencillo modificar el método anterior para sustituir el atributo &lt;code&gt;MetadataType&lt;/code&gt; por una convención de nombrado del tipo “las clases llamadas &lt;code&gt;FooMetadata&lt;/code&gt; contendrán los metadatos de las clases de llamadas &lt;code&gt;Foo&lt;/code&gt;”:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; registerBuddyClassesUsingConventions()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; allAssemblyTypes = &lt;span style="color: #2b91af;"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly().GetTypes().ToList();
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; buddyAssociations =
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;from&lt;/span&gt; t &lt;span style="color: blue;"&gt;in&lt;/span&gt; allAssemblyTypes
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; buddy = allAssemblyTypes
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .FirstOrDefault(other =&amp;gt; other.Name == t.Name + &lt;span style="color: #a31515;"&gt;"Metadata"&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;where&lt;/span&gt; buddy != &lt;span style="color: blue;"&gt;null&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt; { Type = t, Buddy = buddy };
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; association &lt;span style="color: blue;"&gt;in&lt;/span&gt; buddyAssociations)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; descriptionProvider =
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;AssociatedMetadataTypeTypeDescriptionProvider&lt;/span&gt;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; association.Type, association.Buddy
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;TypeDescriptor&lt;/span&gt;.AddProviderTransparent(descriptionProvider, association.Type);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;


       ¿Y si quiero usar IValidatableObject?&lt;/h3&gt;
El interfaz &lt;code&gt;IValidatableObject&lt;/code&gt; (definido &lt;code&gt;System.ComponentModel.DataAnnotations&lt;/code&gt;) obliga a implementar un único método, llamado &lt;code&gt;Validate()&lt;/code&gt;, que retornará una lista de objetos &lt;code&gt;ValidationResult&lt;/code&gt; con los resultados de las comprobaciones.&lt;br /&gt;
&lt;br /&gt;
A continuación se muestra un ejemplo de implementación de este interfaz sobre una entidad:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IValidatableObject&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; Age { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;ValidationResult&lt;/span&gt;&amp;gt; Validate(&lt;span style="color: #2b91af;"&gt;ValidationContext&lt;/span&gt; validationContext)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (Name.Equals(&lt;span style="color: #a31515;"&gt;"albert"&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;StringComparison&lt;/span&gt;.CurrentCultureIgnoreCase))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ValidationResult&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"I don't like Alberts!"&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;strong&gt;El método &lt;code&gt;Validate()&lt;/code&gt; impuesto por el interfaz será invocado automáticamente por el framework&lt;/strong&gt;&amp;nbsp;desde el mismo&amp;nbsp;&lt;code&gt;TryValidateObject()&lt;/code&gt; &lt;strong&gt;siempre que no encuentre errores al comprobar las restricciones especificadas mediante anotaciones&lt;/strong&gt;. O sea, que sólo se invocará a &lt;code&gt;Validate()&lt;/code&gt; cuando no se hayan detectado errores previos de validación (gracias, Arturo, por la aportación).&lt;br /&gt;
&lt;br /&gt;
En cualquier caso, si nos interesa validar de forma manual también estos objetos, siempre podemos hacerlo como sigue:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;ValidationResult&lt;/span&gt;&amp;gt; getIValidatableErrors(&lt;span style="color: blue;"&gt;object&lt;/span&gt; obj)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; validationResults = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;ValidationResult&lt;/span&gt;&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; context = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ValidationContext&lt;/span&gt;(obj, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: blue;"&gt;null&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; validatable = obj &lt;span style="color: blue;"&gt;as&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IValidatableObject&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt;(validatable!=&lt;span style="color: blue;"&gt;null&lt;/span&gt;) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; validationResults.AddRange(validatable.Validate(context));
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; validationResults;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
De esta forma, podríamos comprobar la ejecución como sigue:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; friend = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt; { Age = -1, Name = &lt;span style="color: #a31515;"&gt;"albert"&lt;/span&gt; };
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; errors = getValidationErrors(friend);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; error &lt;span style="color: blue;"&gt;in&lt;/span&gt; errors)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;.WriteLine(error.ErrorMessage);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div style="background-color: black; color: white; font-family: consolas; font-size: 10pt; margin: 10px auto 10px 30px; padding: 3px;"&gt;
The field Age must be between 0 and 120. &lt;br /&gt;
&lt;br /&gt;
I don’t like Alberts! &lt;/div&gt;
En resumen, en este post hemos visto cómo utilizar las herramientas que ofrece el framework .NET para trabajar con validaciones basadas en &lt;em&gt;data annotations&lt;/em&gt; de forma manual, lo que abre su ámbito de utilización a prácticamente cualquier tipo de aplicación para este marco de trabajo. Por el camino hemos repasado los mecanismos de anotaciones, y diversos escenarios como la externalización de atributos en clases buddy o el uso de la interfaz &lt;code&gt;IValidatableObject&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://skydrive.live.com/redir.aspx?cid=c3a43a99b617d787&amp;amp;resid=C3A43A99B617D787!278&amp;amp;parid=C3A43A99B617D787!128&amp;amp;authkey=!AMw05jN0Rcp-1RU"&gt;Descargar un proyecto VS2010 con el código y pruebas desde Skydrive.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-4075930113289782465?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mZ38PlebVjYGbuBJOjQQQz4iZHc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mZ38PlebVjYGbuBJOjQQQz4iZHc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mZ38PlebVjYGbuBJOjQQQz4iZHc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mZ38PlebVjYGbuBJOjQQQz4iZHc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Wu39XxmnfDk:BL-dbgU-9yM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Wu39XxmnfDk:BL-dbgU-9yM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Wu39XxmnfDk:BL-dbgU-9yM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/Wu39XxmnfDk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/4075930113289782465/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=4075930113289782465" title="5 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/4075930113289782465?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/4075930113289782465?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/Wu39XxmnfDk/validacion-manual-con-data-annotations.html" title="Validación manual con Data Annotations" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-y33LGS5zgnE/Tv8yaqnLUTI/AAAAAAAABts/TPejSo7Odpo/s72-c/image%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/02/validacion-manual-con-data-annotations.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYMRHk-fip7ImA9WhRbEEw.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-8834948775836902214</id><published>2012-01-31T08:53:00.001+01:00</published><updated>2012-01-31T14:23:05.756+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T14:23:05.756+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 69</title><content type="html">&lt;a href="http://lh5.ggpht.com/-gVh5uOH2UQI/TyedcmXngwI/AAAAAAAABvc/d9n68quaHoY/s1600-h/image7_thumb_thumb_thumb_thumb2.png"&gt;&lt;img align="right" alt="Enlaces interesantes" border="0" height="129" src="http://lh5.ggpht.com/-kQV8VQ_AqZU/TyeddgEbNUI/AAAAAAAABvk/fslgf51tsn0/image7_thumb_thumb_thumb_thumb_thumb.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes" width="172" /&gt;&lt;/a&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 16 al 29 de enero de 2012. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;

.Net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://whereslou.com/2012/01/24/introducing-dragonfly-another-net-http-server"&gt;&lt;strong&gt;Introducing Dragonfly – another .NET HTTP server&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Louis DeJardin &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geekswithblogs.net/simonc/archive/2012/01/24/inside-the-concurrent-collections-concurrentqueue.aspx"&gt;&lt;strong&gt;Inside the Concurrent Collections: ConcurrentQueue&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simon Cooper &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/csharpfaq/archive/2012/01/23/using-async-for-file-access-alan-berman.aspx"&gt;Using Async for File Access&lt;/a&gt;         &lt;/strong&gt;C# Team &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive-inlining-in-the-clr-4-5-jit.aspx"&gt;Aggressive Inlining in the CLR 4.5 JIT&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Sasha Goldshtein &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx"&gt;What is the defining characteristic of a local variable?&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Eric Lippert &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx" title="Title of this entry"&gt;&lt;strong&gt;C#/.NET Little Pitfalls: Stopwatch Ticks are not TimeSpan Ticks&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;James Michael Hare &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geekswithblogs.net/simonc/archive/2012/01/12/inside-the-concurrent-collections-concurrentstack.aspx" title="Title of this entry"&gt;&lt;strong&gt;Inside the Concurrent Collections: ConcurrentStack&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simon Cooper       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Asp.net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2012/01/23/adding-rich-selector-support-for-mvc.aspx"&gt;&lt;strong&gt;Adding rich Selector support for MVC&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Matt Hidinger &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.collectivematters.com/2012/01/solving-real-world-theming-challenges-with-mvc4-and-sass/"&gt;&lt;strong&gt;Solving Real-world Theming Challenges with MVC4 and Sass&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Harvey Kandola &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/cdndevs/archive/2012/01/23/javascript-and-css-minifying-bundling-with-the-microsoft-web-optimization-nuget-package.aspx"&gt;Javascript and CSS Minifying/Bundling with the Microsoft.Web.Optimization Nuget package&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Maxime Rouiller &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://desarrolloweb.com/articulos/validaciones-propias-aspnet-mvc-dotnet.html"&gt;Validaciones propias en ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Eduard Tomás       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/chunliu/archive/2012/01/20/the-flowchart-of-the-ie-rendering-modes.aspx"&gt;The flowchart of the IE rendering modes&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Chun Liu &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/jeff/archive/2012/01/23/pop-forums-v9-2-posted-to-codeplex-with-new-lanuages-post-voting-and-the-scoring-game.aspx"&gt;POP Forums v9.2 posted to CodePlex, with new languages, post voting and the scoring game&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jeff Putz &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codefrenzy.net/2012/01/23/asp-net-response-redirect/"&gt;ASP.NET Response.Redirect&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Annie Luxton &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://code-inside.de/blog-in/2012/01/23/fix-the-value-x-is-not-valid-for-foo-in-asp-net-mvc"&gt;Fix: the value ‘x’ is not valid for Foo in ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Code Inside Team       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mrubino.net/2012/01/23/deploy-web-con-configuracion-dinamic/"&gt;&lt;strong&gt;Web Deploy – config Transformation&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Marc Rubiño &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jasoft.org/Blog/post/Como-simular-otros-navegadores-para-probar-desarrollos-Web.aspx" title="Cómo simular otros navegadores para probar desarrollos Web"&gt;&lt;strong&gt;Cómo simular otros navegadores para probar desarrollos Web&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/jgalloway/archive/2012/01/17/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides.aspx"&gt;10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jon Galloway &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jasoft.org/Blog/post/Como-obtener-rutas-absolutas-en-ASPNET.aspx" title="Cómo obtener rutas absolutas en ASP.NET"&gt;&lt;strong&gt;Cómo obtener rutas absolutas en ASP.NET&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://mrubino.net/2012/01/17/push-con-singalr/"&gt;Push con SingalR&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Marc Rubiño &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.maartenballiauw.be/post/2012/01/20/Tracking-API-usage-with-Google-Analytics.aspx" title="Tracking API usage with Google Analytics"&gt;&lt;strong&gt;Tracking API usage with Google Analytics&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Maarten Balliauw       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://gregorsuttie.com/2012/01/15/mvc-get-some-help/"&gt;MVC – get some help&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gregor Suttie &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Azure / Cloud&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.estoyenlanube.com/release-de-sql-azure-importexport/"&gt;Release de SQL Azure Import/Export&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ibon Landa &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/scicoria/archive/2012/01/19/making-windows-azure-drive-letter-persistent.aspx"&gt;Making Windows Azure Drive Letter Persistent&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Shawn Cicoria       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2012/01/19/getting-started-with-windows-azure.aspx"&gt;Getting Started with Windows Azure&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Scott Guthrie &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Conceptos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://sebys.com.ar/2012/01/09/gof-singleton/"&gt;&lt;strong&gt;Gof – Singleton&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Sebis &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Data access&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://thedatafarm.com/blog/data-access/what-do-you-want-to-see-in-entity-framework/"&gt;What do you want to see in Entity Framework?&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Julie Lerman &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.heidisql.com/"&gt;HeidiSQL: Windows based interface for managing MySQL and Microsoft SQL databases&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ansgar Becker &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeproject.com/Articles/316816/RaptorDB-The-Key-Value-Store-V2"&gt;RaptorDB - The Key Value Store V2&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Mehdi Gholam &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/01/18/orm-orapoco-trabajando-contra-oracle.aspx"&gt;OraPoco: Trabajando contra Oracle&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Javier Torrecilla &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/diego/archive/2012/01/15/why-entity-framework-vnext-will-be-ef5-and-nothing-else.aspx"&gt;&lt;strong&gt;Why Entity Framework vNext will be EF5 and nothing else&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Diego B. Vega&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Html/Css/Javascript&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/from-jquery-to-javascript-a-reference/"&gt;From jQuery to JavaScript: A Reference&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jeffrey Way &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://lostechies.com/derickbailey/2012/01/24/some-thoughts-on-functional-javascript/"&gt;Some Thoughts On Functional JavaScript&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Derick Bailey       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Elijah Manor &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-coercion/"&gt;&lt;strong&gt;JavaScript for C# developers: coercion&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Julian M. Bucknall       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/gperez/archive/2012/01/25/modernizr-ejemplo-pr-225-ctico-2-utilizando-border-radius-elemento-date-y-atributo-required.aspx"&gt;Modernizr–Ejemplo práctico 2 : Utilizando Border Radius, elemento date y atributo required&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gonzalo Pérez &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://html5doctor.com/server-sent-events/"&gt;Server-Sent Events&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Remy Sharp &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://dotnetslackers.com/articles/aspnet/Using-HTML5-Web-Storage-in-ASP-NET.aspx"&gt;Using HTML5 Web Storage in ASP.NET&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Bipin Joshi &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.etnassoft.com/2012/01/24/creando-objetos-y-aplicaciones-configurables-en-javascript/" title="Enlace permanente a Creando objetos y aplicaciones configurables en Javascript"&gt;&lt;strong&gt;Creando objetos y aplicaciones configurables en Javascript&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Carlos Benítez       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.jquery4u.com/tools/10-excellent-free-rich-text-editors/"&gt;10 Excellent Free Rich-Text Editors&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;jQuery4u &lt;/li&gt;
&lt;li&gt;&lt;a href="http://freshbrewedcode.com/derekgreer/2012/01/22/solid-javascript-the-dependency-inversion-principle/" title="Permanent Link to SOLID JavaScript- The Dependency Inversion Principle"&gt;&lt;strong&gt;SOLID JavaScript- The Dependency Inversion Principle&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Derek Greer       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.kirupa.com/html5/easing_functions_css3.htm"&gt;Easing Functions in CSS3&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Kirupa Chinnathambi &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://jclaes.blogspot.com/2012/01/how-wikipedia-uses-html5-to-save.html"&gt;How Wikipedia uses HTML5 to save bandwidth&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jef Claes       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/"&gt;&lt;strong&gt;The Top 10 Javascript MVC Frameworks Reviewed&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Gordon L. Hempton &lt;/li&gt;
&lt;li&gt;&lt;a href="http://css3.bradshawenterprises.com/" title="Using CSS3 Transitions, Transforms and Animation"&gt;&lt;strong&gt;Using CSS3 Transitions, Transforms and Animation&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Rich Bradshaw &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Visual Studio/Complementos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.jetbrains.com/dotnet/2012/01/importing-exporting-templates-and-patterns-in-resharper-61/"&gt;Importing / Exporting Templates and Patterns in ReSharper 6.1&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Hadi Hariri &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/2012/01/23/c-resharper-awesome-tip-8-extract-class-from-parameters/"&gt;&lt;strong&gt;C# + ReSharper = Awesome: Tip #8 – Extract Class From Parameters&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alvin Ashcraft &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/2012/01/20/c-resharper-awesome-tip-7move-string-to-resource/"&gt;&lt;strong&gt;C# + ReSharper = Awesome: Tip #7–Move String to Resource&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alvin Ashcraft's &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jorge/archive/2012/01/23/stylecop-v4-7-6-0-disponible.aspx"&gt;StyleCop v4.7.6.0 disponible&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jorge Serrano&amp;nbsp;&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Otros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.troyhunt.com/2012/01/breaking-captcha-with-automated-humans.html" title="Breaking CAPTCHA with automated humans"&gt;&lt;strong&gt;Breaking CAPTCHA with automated humans&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Troy Hunt &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://googlecode.blogspot.com/2012/01/lets-make-tcp-faster.html"&gt;Let's make TCP faster&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Yuchung Cheng &lt;/li&gt;
&lt;li&gt;&lt;a href="http://jmalarcon.es/post/El-Cargo-Cult-de-las-pequenas-empresas.aspx"&gt;&lt;strong&gt;El "Cargo Cult" de las pequeñas empresas&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;a href="http://jmalarcon.es/post/El-efecto-Mateo-y-su-influencia.aspx" title="El efecto Mateo y su influencia"&gt;&lt;strong&gt;El efecto Mateo y su influencia&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-8834948775836902214?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=JOq0DjNEN4c:8hHRIyp4svg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=JOq0DjNEN4c:8hHRIyp4svg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=JOq0DjNEN4c:8hHRIyp4svg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/JOq0DjNEN4c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/8834948775836902214/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=8834948775836902214" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/8834948775836902214?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/8834948775836902214?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/JOq0DjNEN4c/enlaces-interesantes-69.html" title="Enlaces interesantes 69" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-kQV8VQ_AqZU/TyeddgEbNUI/AAAAAAAABvk/fslgf51tsn0/s72-c/image7_thumb_thumb_thumb_thumb_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/enlaces-interesantes-69.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQFRngyeSp7ImA9WhRUFEQ.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-7918748243823975697</id><published>2012-01-25T13:25:00.000+01:00</published><updated>2012-01-25T13:25:17.691+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T13:25:17.691+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="libros" /><category scheme="http://www.blogger.com/atom/ns#" term="patrones" /><title>Libro: Dependency injection in .NET</title><content type="html">La inyección de dependencias es uno de esos conceptos rodeados de misterio que parecen reservados a gurús, arquitectos,&amp;nbsp;y otros profesionales &lt;em&gt;de gama alta&lt;/em&gt;, y aplicables exclusivamente en proyectos mastodóndicos.&lt;br /&gt;
&lt;br /&gt;
Y nada más lejos de la realidad: DI se basa en principios relativamente simples, e incluso diría intuitivos, para lograr evitar el acoplamiento entre componentes, es aplicable en todo tipo y tamaño de aplicaciones, y por tanto todas ellas pueden beneficiarse de las ventajas que aporta, como la simplicidad, mantenibilidad, extensibilidad, o facilidad para la realización de pruebas unitarias.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;img align="right" alt="Dependency Injection in .NET. Manning." border="0" height="215" src="http://lh4.ggpht.com/-wJvQO65rEUg/TvnAD2bTtAI/AAAAAAAABtU/sf0YaZLUHHs/image4.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; margin-top: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Dependency Injection in .NET. Manning." width="171" /&gt;Pero, sinceramente, jamás pensé que el tema que pudiera dar tanto de sí como para escribir un libro. Por eso me ha sorprendido la lectura, por cortesía de &lt;a href="http://auges.org/"&gt;Auges&lt;/a&gt;, del libro “&lt;a href="http://www.manning.com/seemann/"&gt;Dependency Injection in .NET&lt;/a&gt;”, escrito por por &lt;a href="http://blog.ploeh.dk/"&gt;Mark Seemann&lt;/a&gt; y publicado por la editorial Manning, donde he podido comprobar que mis conocimientos sobre inyección de dependencias, aunque válidos, eran bastante superficiales.&lt;br /&gt;
&lt;br /&gt;
El libro se estructura en cuatro grandes bloques a través de los cuales se realiza un completo recorrido guiado por los conceptos, utilización y herramientas para aplicar DI:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;“Putting Dependency Injection on the map”&lt;/strong&gt; contiene tres capítulos introductorios, útiles para poner en contexto el patrón y las ventajas que conlleva su uso y describir los conceptos fundamentales utilizados: dependencias, tipos, tiempo de vida, intercepción, contenedores, y muchos otros.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;“DI catalog”&lt;/strong&gt; es una completa relación de patrones de uso de la inyección de dependencias, antipatrones o malos usos que podemos hacer de la misma, y refactorizaciones que podemos utilizar para solucionar escenarios frecuentes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;“DIY DI”&lt;/strong&gt; describe técnicas asociadas a la ID, como la composición de objetos, la gestión del ciclo de vida, y la intercepción de llamadas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;“DI containers”&lt;/strong&gt; es un completo bloque donde se describe el uso de los principales contenedores disponibles para la plataforma .NET: Castle Windsor, StructureMap, Spring.NET, Autofac, Unity y MEF.&lt;/li&gt;
&lt;/ul&gt;
En definitiva, se trata una lectura recomendable para desarrolladores .NET, tanto para aquellos que no hayan tenido experiencia previa con la Inyección de Dependencias y anden buscando fórmulas para reducir el acoplamiento entre componentes, como para los que ya se han enfrentado a ella y desean conocer en mayor profundidad las bases que la sustentan.&lt;br /&gt;
Como puntos negativos, que está disponible exclusivamente en inglés, y que algunos capítulos se hacen algo densos y requieren varias pasadas para poder asimilar las ideas transmitidas.&lt;br /&gt;
&lt;br /&gt;
Enlace: &lt;a href="http://www.manning.com/seemann/" title="http://www.manning.com/seemann/"&gt;http://www.manning.com/seemann/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-7918748243823975697?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=ri35IjEnO_A:YkEvoOIe6ow:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=ri35IjEnO_A:YkEvoOIe6ow:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=ri35IjEnO_A:YkEvoOIe6ow:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/ri35IjEnO_A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/7918748243823975697/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=7918748243823975697" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7918748243823975697?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7918748243823975697?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/ri35IjEnO_A/libro-dependency-injection-in-net.html" title="Libro: Dependency injection in .NET" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-wJvQO65rEUg/TvnAD2bTtAI/AAAAAAAABtU/sf0YaZLUHHs/s72-c/image4.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/libro-dependency-injection-in-net.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYAQX45eCp7ImA9WhRUFE4.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-3328613755633940093</id><published>2012-01-24T09:14:00.002+01:00</published><updated>2012-01-24T19:35:40.020+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-24T19:35:40.020+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desarrollo" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><category scheme="http://www.blogger.com/atom/ns#" term="signalr" /><title>SignalR (II): Conexiones persistentes</title><content type="html">Hace poco estuvimos viendo por aquí &lt;a href="http://www.variablenotfound.com/2012/01/introduccion-signalr-i-conceptos.html"&gt;conceptos básicos sobre SignalR&lt;/a&gt;, el componente que nos permite crear espectaculares aplicaciones en las que múltiples usuarios pueden estar colaborando &lt;strong&gt;de forma simultánea, asíncrona, y en tiempo real&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
Entre otras cosas, comentábamos que SignalR&amp;nbsp; crea una capa de abstracciones sobre una conexión virtual permanente entre cliente y servidor, sobre la que podemos trabajar de diferentes formas:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;mediante &lt;strong&gt;conexiones persistentes&lt;/strong&gt;, la opción de menor nivel, que proporciona mecanismos de notificación de conexión y desconexión de clientes, así como para recibir y enviar mensajes asíncronos a clientes conectados, tanto de forma individual como colectiva. &lt;/li&gt;
&lt;li&gt;mediante el uso de &lt;strong&gt;“hubs”&lt;/strong&gt;, que ofrece una interfaz de desarrollo mucho más sencilla, con una integración entre cliente y servidor que parece pura magia, y que seguro será la opción más utilizada por su potencia y facilidad de uso. &lt;/li&gt;
&lt;/ul&gt;
En este post estudiaremos la primera opción, &lt;strong&gt;conexiones persistentes&lt;/strong&gt;. Los hubs los veremos en un artículo posterior de la serie, aunque si sois impacientes ya podéis ir leyendo el fantástico post del amigo Marc Rubiño sobre el tema, “&lt;a href="http://mrubino.net/2012/01/17/push-con-singalr/"&gt;Push con SignalR&lt;/a&gt;”.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;img align="right" alt="Demo de conexiones persistentes" border="0" height="329" src="http://lh3.ggpht.com/-qRgGWyleqvE/Txxa9_J3MtI/AAAAAAAABvU/5kLBDXUgIJU/image4.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Demo de conexiones persistentes" width="365" /&gt;Bueno, pues vamos al tema: emplearemos esta vía para implementar una funcionalidad bastante simple, pero nada trivial utilizando las herramientas habituales de ASP.NET: mostrar en una página, en tiempo real, información sobre los usuarios que están llegando a ella, los que la abandonan y el número de usuarios que hay conectados justo en ese momento, en tiempo real. &lt;br /&gt;
&lt;br /&gt;
Para ello haremos lo siguiente:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;En el lado servidor, &lt;strong&gt;implementaremos un servicio (endpoint) SignalR&lt;/strong&gt;, que es el que procesará las conexiones y desconexiones de clientes, y enviará información actualizada por las conexiones abiertas. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Registraremos este endpoint durante la inicialización&lt;/strong&gt; de la aplicación, asociándole una URL de acceso a las funcionalidades del servicio. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;En el lado cliente implementaremos la conexión con el servicio&lt;/strong&gt;, capturaremos la información que nos vaya enviando y la mostraremos en la página en forma de log. &lt;/li&gt;
&lt;/ol&gt;
El resultado lucirá tal y como se muestra en la captura de pantalla adjunta. Aunque si lo preferís, podéis verlo en vivo y en directo descargando y ejecutando el proyecto de demostración que encontraréis al final de este artículo.&lt;br /&gt;
&lt;br /&gt;
Ya en el post anterior de la serie vimos cómo &lt;a href="http://www.variablenotfound.com/2012/01/introduccion-signalr-i-conceptos.html"&gt;descargar e instalar SignalR en un proyecto&lt;/a&gt;, así que vamos a suponer que ese paso ya lo hemos realizado previamente.&lt;br /&gt;
&lt;h3&gt;



1. Implementación del endpoint&lt;/h3&gt;
El endpoint, o servicio SignalR, que vamos a implementar utilizando el enfoque de conexión persistente es simplemente una clase que hereda de &lt;code&gt;SignalR.PersistentConnection&lt;/code&gt;, en la que podemos sobrescribir los métodos que necesitemos para implementar nuestras funcionalidades. En ella encontramos métodos como &lt;code&gt;OnConnected()&lt;/code&gt;, &lt;code&gt;OnDisconnect()&lt;/code&gt;, &lt;code&gt;OnReceived()&lt;/code&gt;, y bastantes más, que nos permiten tomar el control cuando se producen determinados eventos de interés en la conexión:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;VisitorsService&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;PersistentConnection&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp; OnConnected(&lt;span style="color: #2b91af;"&gt;HttpContextBase&lt;/span&gt; context, &lt;span style="color: blue;"&gt;string&lt;/span&gt; clientId) { ... }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp; OnDisconnect(&lt;span style="color: blue;"&gt;string&lt;/span&gt; clientId) { ... }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp; OnReceived(&lt;span style="color: blue;"&gt;string&lt;/span&gt; clientId, &lt;span style="color: blue;"&gt;string&lt;/span&gt; data) { ... }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// [...]&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Observad que el interfaz es bastante similar a la que encontramos al trabajar directamente con sockets: podemos introducir lógica cuando un nuevo cliente se conecte sobrescribiendo el método &lt;code&gt;OnConnected()&lt;/code&gt;,&amp;nbsp; cuando se desconecte, haciendo lo propio con &lt;code&gt;OnDisconnect()&lt;/code&gt;, o cuando el cliente envíe algún tipo de mensaje al servidor, que ejecutará la funcionalidad implementada en &lt;code&gt;OnReceived()&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
De la misma forma, la clase base &lt;code&gt;PersistentConnection&lt;/code&gt; ofrece mecanismos para &lt;strong&gt;enviar mensajes directos a un cliente, a grupos de ellos, o a todos los clientes conectados&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Volviendo al sistema que estamos desarrollando, básicamente para alcanzar nuestros objetivos necesitamos:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;tomar el control en el momento en que se produce una nueva conexión (método &lt;code&gt;OnConnected&lt;/code&gt;), momento en que enviaremos al resto de clientes un mensaje con información sobre el cliente conectado y el total de conexiones activas. &lt;/li&gt;
&lt;li&gt;tomar el control en el momento en que se produce la desconexión de un cliente (método &lt;code&gt;OnDisconnect()&lt;/code&gt;), para notificar al resto y actualizarles el número de clientes conectados. &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;



1.1. Notificando a los clientes las nuevas conexiones &lt;/h4&gt;
Cuando se realiza una nueva conexión al servicio, es decir, la llegada de un nuevo cliente, SignalR invocará al método &lt;code&gt;OnConnected()&lt;/code&gt; del &lt;em&gt;endpoint&lt;/em&gt; suministrándole el contexto de la petición HTTP actual, y un “ClientId”. El primero nos puede ser muy interesante para &lt;strong&gt;acceder a información de la petición&lt;/strong&gt; (como el navegador, IP, cookies, información de autenticación, etc.), y el segundo es un &lt;strong&gt;identificador único generado por SignalR&lt;/strong&gt; para realizar el seguimiento de la conexión.&lt;br /&gt;
&lt;br /&gt;
Implementamos nuestro método y lo comentamos justo a continuación:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnConnected(&lt;span style="color: #2b91af;"&gt;HttpContextBase&lt;/span&gt; context, &lt;span style="color: blue;"&gt;string&lt;/span&gt; clientId)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; clientDescription = getClientDescription(context);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _clients.TryAdd(clientId, clientDescription);
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; text = clientDescription + &lt;span style="color: #a31515;"&gt;" arrived."&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; msg = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;NotificationMessage&lt;/span&gt;(text, _clients.Count);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Connection.Broadcast(msg);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Lo primero que hacemos en la implementación del método es obtener una descripción textual del cliente (que puede ser el nombre del usuario autenticado, o su IP), utilizando el método &lt;code&gt;getClientDescription()&lt;/code&gt;, que veremos más adelante. Esta descripción, asociada al ClientId, es almacenada en el diccionario estático &lt;code&gt;_clients&lt;/code&gt;, lo que nos permitirá conocer en todo momento los clientes conectados.&lt;br /&gt;
&lt;br /&gt;
Justo después componemos el mensaje y realizamos el envío a todos los usuarios conectados invocando el método &lt;code&gt;Broadcast()&lt;/code&gt; de la propiedad de instancia &lt;code&gt;Connection&lt;/code&gt;, que nos da acceso al canal virtual abierto entre clientes y servidor. El parámetro que recibe este método es de tipo &lt;code&gt;object&lt;/code&gt;, y viajará serializado en formato JSON hasta cada uno de los clientes conectados; en este caso, hemos creado una clase llamada &lt;code&gt;NotificationMessage&lt;/code&gt; que contiene toda la información que necesitamos suministrarles:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;NotificationMessage&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; NotificationMessage(&lt;span style="color: blue;"&gt;string&lt;/span&gt; message, &lt;span style="color: blue;"&gt;int&lt;/span&gt; onlineUsers)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnlineUsers = onlineUsers;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message = message;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Date
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; System.&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Now.ToLongTimeString(); }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Message { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; OnlineUsers { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Es conveniente tener en cuenta, sin embargo, que es posible enviar cualquier tipo de objeto: tipos propios (como en el ejemplo anterior), objetos anónimos, primitivos, o lo que se nos ocurra. Simplemente será serializado como JSON y llegará al cliente de forma directa (más adelante veremos cómo).&lt;br /&gt;
&lt;br /&gt;
Los miembros auxiliares utilizados en el código anterior son los siguientes:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ConcurrentDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; _clients =
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ConcurrentDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt;();
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; getClientDescription(&lt;span style="color: #2b91af;"&gt;HttpContextBase&lt;/span&gt; context)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; browser = context.Request.Browser.Browser + &lt;span style="color: #a31515;"&gt;" "&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.Request.Browser.Version;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; name = context.Request.IsAuthenticated ?
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"User "&lt;/span&gt; + context.User.Identity.Name :
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"IP "&lt;/span&gt; + context.Request.UserHostAddress;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; name + &lt;span style="color: #a31515;"&gt;" ("&lt;/span&gt; + browser + &lt;span style="color: #a31515;"&gt;")"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Observad que el diccionario donde almacenamos la información sobre las conexiones ha sido definido como &lt;code&gt;ConcurrentDictionary&lt;/code&gt; para evitar problemas de concurrencia durante las actualizaciones, y es estático para que su información sea compartida entre todas las instancias del servicio.&lt;br /&gt;
&lt;h4&gt;



1.2. Notificando a los clientes las desconexiones &lt;/h4&gt;
Cuando SignalR detecta que un cliente se ha desconectado, invocará al método virtual &lt;code&gt;OnDisconnect()&lt;/code&gt; del &lt;em&gt;endpoint&lt;/em&gt;, lo cual nos permite introducir lógica de gestión del evento. En nuestro caso, simplemente necesitamos eliminar al cliente del diccionario donde los estamos almacenando, &lt;br /&gt;
&lt;br /&gt;
De la misma forma, debemos controlar las desconexiones para notificar este hecho a los clientes aún conectados, para lo que sobrescribimos el método &lt;code&gt;OnDisconnect()&lt;/code&gt;:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnDisconnect(&lt;span style="color: blue;"&gt;string&lt;/span&gt; clientId)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; text, clientDescription;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (_clients.TryRemove(clientId, &lt;span style="color: blue;"&gt;out&lt;/span&gt; clientDescription))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = clientDescription + &lt;span style="color: #a31515;"&gt;" is leaving."&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = &lt;span style="color: #a31515;"&gt;"Unknown user leaving."&lt;/span&gt;;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; msg = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;NotificationMessage&lt;/span&gt;(text, _clients.Count);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Connection.Broadcast(msg);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
En este método recibimos el ClientId que SignalR asignó al cliente en el momento de iniciar la conexión; lo único que hacemos es buscarlo en el diccionario de clientes donde los estamos almacenando, eliminarlo, y enviar un mensaje broadcast al resto de usuarios indicando la desconexión que se ha producido.&lt;br /&gt;
&lt;br /&gt;
Cuando implementéis funcionalidades en la desconexión, tened en cuenta que &lt;strong&gt;SignalR tarda unos segundos en darse cuenta de las desconexiones&lt;/strong&gt; (recordad que con el transporte utilizado por defecto se trata de una conexión persistente virtual) por lo que puede aparecer un leve retraso en las notificaciones. Estos tiempos, en cualquier caso, pueden ser configurados (en el proyecto de demostración podéis ver cómo hacerlo).&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;[Actualización]&lt;/strong&gt;: como bien indica Arturo en un comentario del post, &lt;strong&gt;para que las desconexiones sean notificadas correctamente es necesario utilizar IIS o IIS Express&lt;/strong&gt;. Con Cassini (el servidor web integrado en VS) no funcionará bien este mecanismo.&lt;br /&gt;
&lt;h4 id="observaciones"&gt;



1.3. Algunas observaciones adicionales&lt;/h4&gt;
Al principio de comenzar a jugar con conexiones persistentes de SignalR, una de las cosas que pueden llamar la atención es que si en la implementación del método &lt;code&gt;OnConnected()&lt;/code&gt; enviamos un broadcast a todos los usuarios conectados,&amp;nbsp; el usuario actual (el que ha provocado la llamada a &lt;code&gt;OnConnected&lt;/code&gt;) no recibirá el mensaje; o en otras palabras, &lt;strong&gt;el broadcast llegará a todos los clientes excepto al que acaba de realizar la conexión&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Desconozco si se trata de un comportamiento por diseño, si es algo que se modificará en posteriores revisiones de SignalR (recordemos que en estos momentos es todavía una versión preliminar), o si simplemente se trata de un nombre para el método poco afortunado, pues en mi opinión da a entender que la conexión ya ha sido realizada y, por tanto, el broadcast debería llegarle también.&lt;br /&gt;
&lt;br /&gt;
Pero en cualquier caso, en la implementación del proyecto de pruebas que podéis descargar al final de este post veréis cómo lo he solucionado incluyendo una llamada explícita (“ping”) desde el cliente al servidor para forzar el envío de un mensaje de actualización justo después de completarse la conexión. Conceptualmente, lo que se hace es:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;desde el cliente, una vez se ha realizado la conexión, realizar un envío de datos al servidor, algo similar a un “ping”, &lt;/li&gt;
&lt;li&gt;en el método &lt;code&gt;OnReceived()&lt;/code&gt; del servidor, capturar el mensaje enviado desde el cliente y responderle de forma directa con la información que nos interese hacerle llegar, que podría ser un mensaje de bienvenida y, como en otras ocasiones, el número de usuarios conectados:&amp;nbsp;&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnReceived(&lt;span style="color: blue;"&gt;string&lt;/span&gt; clientId, &lt;span style="color: blue;"&gt;string&lt;/span&gt; data)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; msg = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;NotificationMessage&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Hi!"&lt;/span&gt;, _clients.Count);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Send(clientId, msg);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
Más adelante, cuando tratemos la parte cliente del servicio, veremos cómo está implementado el envío desde el cliente de este “ping”.&lt;br /&gt;
&lt;h3&gt;



2. Registro de ruta&lt;/h3&gt;
&lt;strong&gt;Una vez tenemos el servicio implementado, debemos registrar en el sistema de routing&lt;/strong&gt; de ASP.NET una URL a través de la cual será posible acceder al mismo. El lugar idóneo para hacerlo, como siempre que se trata de cargar la tabla de rutas, es en el global.asax, para que se ejecute durante la inicialización de la aplicación.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, en una aplicación ASP.NET MVC podría ser algo así:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; RegisterSignalrConnections(&lt;span style="color: #2b91af;"&gt;RouteCollection&lt;/span&gt; routes)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; routes.MapConnection&amp;lt;&lt;span style="color: #2b91af;"&gt;VisitorsService&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515;"&gt;"Visitors"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"VisitorsService/{*operation}"&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; Application_Start()
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RegisterSignalrConnections(&lt;span style="color: #2b91af;"&gt;RouteTable&lt;/span&gt;.Routes);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [...]
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Observad que lo único que estamos haciendo es añadir a la tabla de rutas una entrada en la que asociamos el servicio, en este caso nuestra clase &lt;code&gt;VisitorsService&lt;/code&gt;, a la dirección “&lt;code&gt;VisitorsService/{*operation}&lt;/code&gt;”, que será la URL de acceso al mismo. &lt;br /&gt;
&lt;br /&gt;
El primer parámetro que enviamos al método &lt;code&gt;MapConnection()&lt;/code&gt; es simplemente el nombre de la entrada en la tabla de rutas, no tiene demasiada importancia.&lt;br /&gt;
&lt;h3&gt;



3. Implementación del cliente web&lt;/h3&gt;
La implementación de clientes web para las conexiones persistentes desarrolladas con SignalR es bastante simple, y comienza incluyendo en la página o vista una &lt;strong&gt;referencia hacia la biblioteca cliente&lt;/strong&gt; de este componente:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;src&lt;/span&gt;&lt;span style="color: blue;"&gt;="&lt;/span&gt;&lt;span style="background-attachment: scroll; background-image: none; background-repeat: repeat;"&gt;&lt;span style="background-color: yellow;"&gt;@&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;Url.Content(&lt;/span&gt;&lt;span style="color: #a31515;"&gt;"~/Scripts/jquery.signalR.js"&lt;/span&gt;&lt;span style="color: blue;"&gt;)"&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue; font-size: 10pt;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Como siempre, esta inclusión puede realizarse a nivel de página, o bien en la Master o Layout si queremos aplicarlo a todas las vistas del sistema.&lt;br /&gt;
&lt;blockquote&gt;
Nota: si queremos dar soporte a clientes antiguos que no soportan deserialización&amp;nbsp;JSON de forma nativa (por ejemplo, IE7), será necesario descargar desde Nuget la biblioteca de scripts json2.js y referenciarla en la página antes de la carga de SignalR.js. En caso contrario, se lanzará una excepción con el error:&lt;br /&gt;
&lt;br /&gt;
“SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE&amp;lt;8”&amp;nbsp;&lt;/blockquote&gt;
Centrándonos en nuestra aplicación, el marcado HTML será tan simple como el que se muestra a continuación, lo único que hacemos es dejar un “hueco” en el que introduciremos los mensajes que se vayan recibiendo del servidor:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: maroon;"&gt;h2&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Log&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;h2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="log"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue; font-size: 10pt;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
A continuación, necesitamos implementar el código de script que realice las siguientes tareas:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;iniciar la conexión&lt;/strong&gt; con el endpoint, &lt;/li&gt;
&lt;li&gt;tras ello, &lt;strong&gt;enviar un “ping”&lt;/strong&gt; para recibir el mensaje de bienvenida (recordad lo que os &lt;a href="http://www.blogger.com/blogger.g?blogID=27752126#observaciones"&gt;comentaba previamente&lt;/a&gt; de que el broadcast no se recibe por el cliente que inicia la conexión), &lt;/li&gt;
&lt;li&gt;mostrar en el log la información recibida del servidor.&lt;/li&gt;
&lt;/ul&gt;
Y el código de script tampoco puede ser más sencillo:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: blue;"&gt;function&lt;/span&gt; () {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; conn = $.connection(&lt;span style="color: maroon;"&gt;"VisitorsService"&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn.received(&lt;span style="color: blue;"&gt;function&lt;/span&gt; (data) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; text = data.Date + &lt;span style="color: maroon;"&gt;" - "&lt;/span&gt; + data.Message + &lt;span style="color: maroon;"&gt;" "&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data.OnlineUsers + &lt;span style="color: maroon;"&gt;" users online."&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: maroon;"&gt;'#log'&lt;/span&gt;).prepend(&lt;span style="color: maroon;"&gt;"&amp;lt;div&amp;gt;"&lt;/span&gt; + text + &lt;span style="color: maroon;"&gt;"&amp;lt;/div&amp;gt;"&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn.start(&lt;span style="color: blue;"&gt;function&lt;/span&gt; () {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn.send(&lt;span style="color: maroon;"&gt;"ping"&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });
&amp;nbsp;&amp;nbsp;&amp;nbsp; });
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue; font-size: 10pt;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Lo comentamos muy rápidamente:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;en la variable &lt;code&gt;conn&lt;/code&gt; obtenemos una referencia hacia el &lt;em&gt;endpoint&lt;/em&gt;, identificado por el nombre de la conexión persistente, en este caso, &lt;code&gt;VisitorsService&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;sobre ella, definimos la función &lt;code&gt;received()&lt;/code&gt;, que será invocada cuando el servidor envíe información. El parámetro que recibe la función anónima es la información enviada desde el servidor, que, recordaréis, en este caso se trataba en objetos de tipo &lt;code&gt;NotificationMessage&lt;/code&gt;. Dado que la serialización y deserialización se realizan de forma automática, podemos acceder directamente a sus miembros, como podéis ver en el código para montar el mensaje e introducirlo en el log. &lt;/li&gt;
&lt;li&gt;por último, iniciamos la conexión invocando al método &lt;code&gt;start()&lt;/code&gt; de la conexión. Observad que este método admite un callback que será llamado cuando la conexión se haya establecido, momento que aprovechamos para enviar el “ping” al servidor que nos permitirá recibir el mensaje de bienvenida.&lt;/li&gt;
&lt;/ul&gt;
Y ¡esto es todo! &lt;br /&gt;
&lt;br /&gt;
Si tenéis un ratillo, no dejéis de descargar el proyecto de prueba y jugar un rato con él. Y sobre todo, observad las pocas líneas de código que hemos tenido que emplear para resolver esta funcionalidad y comparadlo con lo que supondría implementarla de forma artesana, con las técnicas tradicionales.&lt;br /&gt;
&lt;a href="https://skydrive.live.com/redir.aspx?cid=c3a43a99b617d787&amp;amp;resid=C3A43A99B617D787!280&amp;amp;parid=C3A43A99B617D787!279&amp;amp;authkey=!APhkeh3_sBUH3nk"&gt;Descargar proyecto de prueba&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;En el próximo post de la serie veremos cómo utilizar los Hubs&lt;/strong&gt; de SignalR, un planteamiento con una abstracción aún mayor sobre la conexión y una integración entre cliente y servidor simplemente espectacular.&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-3328613755633940093?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=CJXxK_fjlTE:zT4Qx0M00AQ:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=CJXxK_fjlTE:zT4Qx0M00AQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=CJXxK_fjlTE:zT4Qx0M00AQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/CJXxK_fjlTE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/3328613755633940093/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=3328613755633940093" title="7 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3328613755633940093?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3328613755633940093?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/CJXxK_fjlTE/signalr-ii-conexiones-persistentes.html" title="SignalR (II): Conexiones persistentes" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-qRgGWyleqvE/Txxa9_J3MtI/AAAAAAAABvU/5kLBDXUgIJU/s72-c/image4.png?imgmax=800" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/signalr-ii-conexiones-persistentes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8DQnY7fCp7ImA9WhRUFUw.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-7220179047086470305</id><published>2012-01-17T20:58:00.000+01:00</published><updated>2012-01-25T19:41:13.804+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T19:41:13.804+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desarrollo" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="signalr" /><title>Introducción a SignalR (I): Conceptos básicos</title><content type="html">&lt;img align="right" alt="Uau!!" border="0" height="157" src="http://lh6.ggpht.com/-nD6ITJOSkno/TxQj-U7Y4yI/AAAAAAAABuk/T2HeCKsE7HM/image61.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Uau!!" width="159" /&gt;Una aplicación que mezcla &lt;strong&gt;internet, asincronía, y múltiples usuarios colaborando e interactuando al mismo&lt;/strong&gt; tiempo siempre es merecedora de un “¡uau!”. Seguro que, al igual que un servidor, en algún momento os habéis quedado maravillados con la interactividad que presentan algunos sistemas web modernos, como Facebook, Google Docs, o muchos otros, en las que estamos recibiendo actualizaciones, prácticamente en tiempo real, sin necesidad de recargar la página. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo, en Google Docs, si estamos editando un documento online y otro usuario accede al mismo, podemos ver sobre la marcha que ha entrado, e incluso las modificaciones que va realizando sobre el documento. O algo más cotidiano, en un simple chat vía web van apareciendo los mensajes tecleados por nuestros compañeros de sala como por arte de magia. Ambos sistemas utilizan el mismo tipo de solución: el envío &lt;strong&gt;asíncrono de datos entre servidor y clientes en tiempo real&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
En esta serie de artículos veremos cómo podemos implementar sorprendentes funcionalidades de este tipo utilizando SignalR, un framework&amp;nbsp;open source desarrollado por gente del equipo de ASP.NET, que nos facilitará bastante la tarea.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;



¿Cómo puede el servidor enviar eventos al cliente de forma asíncrona?&lt;/h3&gt;
Crear este tipo de sistemas usando herramientas convencionales nos puede causar algunos dolores de cabeza, principalmente porque los protocolos que sustentan la web están basados en un modelo cliente-servidor síncrono: uno o varios clientes realizan una conexión hacia el servidor y le transmiten una acción a realizar, éste la procesa y les retorna la respuesta, cerrándose la conexión de forma inmediata.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="right" alt="Polling" border="0" height="266" src="http://lh6.ggpht.com/-DxUukW_-2DI/TxQj_Ejdo6I/AAAAAAAABuo/XikeoudxXuk/image9.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Polling" width="197" /&gt;A priori, no hay forma de que el servidor sea el que notifique a los clientes los cambios de estado (por ejemplo, la llegada en un chat de un mensaje procedente de otro usuario), salvo que éstos utilicen un mecanismo de &lt;em&gt;polling&lt;/em&gt;, es decir, que estén continuamente estableciendo conexiones con el servidor para ver si hay algún nuevo evento a tener en cuenta. &lt;br /&gt;
&lt;br /&gt;
Aunque válido en determinados escenarios, hay otros en los que se trata de una solución demasiado costosa, sobre todo cuando hay que gestionar un alto número de clientes conectados.&lt;br /&gt;
&lt;br /&gt;
El ideal sería utilizar una conexión persistente, siempre abierta, entre cliente y servidor, que permitiría el envío y recepción de mensajes y eventos de forma bidireccional entre ambos. De esta forma, si el servidor tiene algo que enviar a sus clientes, simplemente tendría que transmitirlo por el canal que mantendría abierto con cada uno de ellos.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="left" alt="Conexión persistente" border="0" height="222" src="http://lh4.ggpht.com/-lEWF_YRWjw4/TxQj_t35PCI/AAAAAAAABu0/Ydbxj4HNvG8/image13.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: left; margin: 0px 10px 10px 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Conexión persistente" width="202" /&gt;Sin embargo, hasta ahora esto sólo se podía conseguir usando sockets, lo cual, en entorno web, requería la existencia de algún tipo de elemento activo sobre la página (Silverlight, Flash, o applets Java, por ejemplo) capaz de establecer este tipo de comunicaciones.&lt;br /&gt;
&lt;br /&gt;
Afortunadamente, la W3C parece dispuesta a cambiar esta situación al introducir de forma nativa los famosos WebSockets, cuya &lt;a href="http://dev.w3.org/html5/websockets/"&gt;definición se encuentra todavía en borrador&lt;/a&gt;. Esta nueva API permitirá abrir conexiones directas desde el navegador usando Javascript, por lo que podría ayudarnos bastante una vez su implementación sea universal en los agentes de usuario. De momento no es así, aunque ya está disponible en algunos de ellos (&lt;a href="http://html5demos.com/web-socket"&gt;podéis ver una demo simple aquí&lt;/a&gt; con Chrome).&lt;br /&gt;
&lt;img align="right" alt="Logo de HTML5" border="0" height="155" src="http://lh5.ggpht.com/-6oLrTSyQIbQ/TxQkAho-q6I/AAAAAAAABu8/d9ynr_E8i_g/image41.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Logo de HTML5" width="155" /&gt;&lt;br /&gt;
También existe otra iniciativa de la W3C que podría ayudar a enviar mensajes o eventos desde el servidor a los clientes suscritos, llamada &lt;a href="http://dev.w3.org/html5/eventsource/"&gt;Server-Sent Events&lt;/a&gt;. Como en el caso anterior, se encuentra en borrador, aunque ya algunos navegadores lo implementan (&lt;a href="http://googlecodesamples.com/html5/sse/sse.html"&gt;podéis ver una demo aquí&lt;/a&gt; con Chrome), por lo que todavía no podemos utilizarla de forma segura.&lt;br /&gt;
&lt;br /&gt;
Por esta razón, existen hoy en día múltiples soluciones que permiten solventar las limitaciones del protocolo, como las englobadas bajo la denominación &lt;a href="http://es.wikipedia.org/wiki/Tecnolog%C3%ADa_Push"&gt;Server push&lt;/a&gt; o &lt;a href="http://en.wikipedia.org/wiki/Comet_(programming)"&gt;Comet&lt;/a&gt;, aprovechando los recursos existentes en los protocolos utilizados para crear, o al menos simular, este canal abierto continuo entre cliente y servidor utilizando &lt;a href="http://ajaxpatterns.org/Periodic_Refresh"&gt;polling&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/Tecnolog%C3%ADa_Push#Long_polling"&gt;long polling&lt;/a&gt;, &lt;a href="http://ajaxpatterns.org/HTTP_Streaming"&gt;HTTP streaming&lt;/a&gt;, y otros artificios.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="left" alt="Long polling" border="0" height="219" src="http://lh5.ggpht.com/-iPq8DEdAyg4/TxQkB_WRebI/AAAAAAAABvE/gPNWXaGnFIY/image17.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: left; margin: 0px 10px 10px 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Long polling" width="204" /&gt;Por ejemplo, el mecanismo &lt;em&gt;long polling&lt;/em&gt; utiliza peticiones HTTP para crear una conexión “pseudopersistente”. El servidor, en lugar de procesar la petición y retornar la respuesta de forma inmediata, espera hasta que haya disponible algún evento o mensaje a enviar al cliente; en este momento, lo retorna como respuesta a la petición original y cierra la conexión. El cliente, por su parte, procesa esta respuesta y realiza inmediatamente después una nueva petición al servidor, que volverá a quedar abierta a la espera de mensajes, y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
En definitiva, se trata de un mecanismo más limpio y eficiente que el polling, puesto que evita gran cantidad de peticiones absurdas que se producen cuando en el servidor no hay eventos pendientes de notificar. Además, dado que utiliza HTTP estándar, es válida para todo tipo de agentes de usuario, y bastante amigable para proxies, filtros, firewalls y otros inconvenientes que puede haber por el camino entre los dos extremos.&lt;br /&gt;
&lt;br /&gt;
Y en este punto es donde entra en escena &lt;a href="https://github.com/SignalR/SignalR"&gt;SignalR&lt;/a&gt;, un conjunto de componentes desarrollados por &lt;a href="http://twitter.com/#!/DamianEdwards"&gt;Damian Edwards&lt;/a&gt; y &lt;a href="http://twitter.com/#!/davidfowl/"&gt;David Fowler&lt;/a&gt;, miembros del equipo de ASP.NET en Microsoft, que nos abstrae de los detalles subyacentes y nos ofrece la visión y ventajas de un entorno conectado en el que podemos comunicar cliente y servidor bidireccionalmente, de forma asíncrona, y con una sencillez pasmosa. SignalR nos hace ver como si cliente y servidor estuvieran conectados de forma continua y facilita el envío de mensajes asíncronos bidireccionales entre ambos extremos.&lt;br /&gt;
&lt;br /&gt;
Por último, es importante decir que SignalR no es específico para ASP.NET MVC, ni para WebForms: &lt;strong&gt;podemos utilizarlo con cualquier tipo de proyecto web&lt;/strong&gt;. De hecho, incluso se puede utilizar en otro tipo de proyectos usando un servidor self-hosted :-)&lt;br /&gt;
&lt;h3&gt;



SignalR, conceptualmente&lt;/h3&gt;
SignalR ofrece una visión a muy alto nivel de la comunicación entre el servidor y los múltiples clientes que se encuentren a él conectados. Y cuando digo “alto nivel”, creedme que estoy hablando de muchos metros de altura ;-)&lt;br /&gt;
&lt;br /&gt;
Como desarrolladores, &lt;strong&gt;trabajaremos sobre una conexión virtualmente siempre abierta&lt;/strong&gt;: en servidor podremos detectar cuándo se ha conectado un nuevo cliente, cuándo se ha desconectado, recibir mensajes de éstos, enviar mensajes a los clientes conectados…, en definitiva, todo lo que podemos necesitar para crear aplicaciones asíncronas multiusuario.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, en realidad estas conexiones persistentes no existen, o no tienen por qué existir. Se trata de una abstracción creada por SignalR, que el que se encargará del trabajo sucio que hay por debajo, manteniendo la conexión de los clientes con el servidor mediante distintos mecanismos denominados “transportes”, que son el conjunto de tecnologías utilizadas para mantener crear la conexión continua, o al menos la ilusión de su existencia.&lt;br /&gt;
&lt;br /&gt;
Lo interesante de los protocolos de transporte es que pueden ser sustituidos de forma transparente sin afectar a nuestras aplicaciones, que trabajarán aisladas de estos detalles. Nuestros sistemas funcionarán exactamente igual sea cual sea el transporte utilizado, lo que permite que éste sea elegido en cada escenario en función de la disponibilidad de las tecnologías en ambos extremos. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo, el transporte &lt;em&gt;Websockets&lt;/em&gt; es capaz de crear una conexión con el servidor y mantenerla abierta de forma continua, aunque requiere que esta tecnología esté disponible tanto en el cliente (en el caso de clientes web, es necesario que el navegador implemente Websockets) como en el servidor.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="right" alt="Long polling, el transporte utilizado por defecto en SignalR" border="0" height="219" src="http://lh6.ggpht.com/-44ec-CVvFd8/TxQkC_3yDII/AAAAAAAABvI/98CA-8MrXnk/image21.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Long polling, el transporte utilizado por defecto en SignalR" width="204" /&gt;Debido a ello, y para asegurar la máxima compatibilidad con los clientes, actualmente se utiliza por defecto el transporte denominado &lt;em&gt;Long polling&lt;/em&gt;, que ya hemos comentado anteriormente.&lt;br /&gt;
&lt;br /&gt;
Observad que, a pesar de la relativa complejidad que supondría implementar algo así a mano, nosotros no tendremos que hacer nada: SignalR se encarga de llevar a cabo todas estas tareas para ofrecernos la sensación de estar siempre conectados.&lt;br /&gt;
&lt;br /&gt;
Su componente cliente será el encargado de realizar las conexiones, mantenerse a la espera de noticias del servidor, reconectar cuando se reciban eventos o cuando por cualquier otra causa se haya perdido la conectividad, etc., ofreciéndonos una superficie de desarrollo muy simplificada.&lt;br /&gt;
&lt;br /&gt;
El lado servidor de SignalR, por otra parte, será el encargado de recibir la conexión y mantenerla en espera, almacenar los mensajes recibidos, realizar el seguimiento de clientes conectados, enviar mensajes a través de un bus interno, etc., y de la misma forma, ofreciéndonos un API bastante simple para implementar nuestros servicios.&lt;br /&gt;
&lt;h3&gt;



Implementación de servicios con SignalR&lt;/h3&gt;
SignalR nos ofrece dos fórmulas para trabajar sobre las conexiones que crea con el servidor: &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;usando “conexiones persistentes”&lt;/strong&gt;, es la de más bajo nivel y proporciona mecanismos simples para registrar conexiones y desconexiones de clientes y comunicarse de forma bidireccional con ellos. De hecho, esta forma de crear servicios es &lt;strong&gt;bastante similar a como hacemos utilizando sockets&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;usando “hubs”&lt;/strong&gt;, que ofrece una abstracción aún mayor, permitiendo la comunicación entre cliente y servidor de forma casi mágica. Esta es la opción que convendrá utilizar en la mayoría de ocasiones, por la potencia que aporta y su gran comodidad de uso. &lt;/li&gt;
&lt;/ul&gt;
En cualquiera de los dos casos, y ya centrándonos en el entorno web más habitual, donde el servidor es una aplicación ASP.NET y los clientes van a ser las páginas o vistas en las que tendremos un motor de scripting, la implementación de servicios consistirá en:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;en el servidor, crear el servicio (también llamado &lt;em&gt;endpoint&lt;/em&gt;) con las funcionalidades que nos interese, utilizando las clases disponibles en el ensamblado SignalR. &lt;/li&gt;
&lt;li&gt;en cliente, crear el consumidor del servicio utilizando las clases disponibles en la biblioteca de scripts &lt;em&gt;jQuery.SignalR.js&lt;/em&gt; (o su correspondiente versión minimizada). &lt;/li&gt;
&lt;/ul&gt;
Cada una de las dos fórmulas citadas tiene sus particularidades, por lo que las estudiaremos mediante el desarrollo de &lt;strong&gt;ejemplos independientes en futuros posts de la serie&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Pero primero, veamos rápidamente cómo podemos incluir este componente en nuestros proyectos, aunque desde luego más sencillo no puede ser… ;-)&lt;br /&gt;
&lt;h3&gt;



Instalación de SignalR&lt;/h3&gt;
El sitio web oficial del producto (&lt;a href="http://www.campusmvp.com/Catalogo/Product-Desarrollo-Web-con-ASP.NET-MVC-3_92.aspx"&gt;signalr.net&lt;/a&gt;), a día de hoy, es una simple redirección hacia &lt;a href="https://github.com/SignalR/SignalR"&gt;Github&lt;/a&gt;, donde se encuentra la documentación y el código fuente del proyecto. Aunque podríamos descargarlo desde ahí, la opción más sencilla, como siempre, es utilizar Nuget:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;PM&amp;gt; &lt;span style="background-color: yellow;"&gt;Install-Package signalr&lt;/span&gt;
Attempting to resolve dependency 'SignalR.Server (≥ 0.3.5)'.
Attempting to resolve dependency 'Microsoft.Web.Infrastructure (≥ 1.0.0.0)'.
Attempting to resolve dependency 'SignalR.Js (≥ 0.3.5)'.
Attempting to resolve dependency 'jQuery (≥ 1.6)'.
Successfully installed 'Microsoft.Web.Infrastructure 1.0.0.0'.
Successfully installed 'SignalR.Server 0.3.5'.
Successfully installed 'SignalR.Js 0.3.5'.
Successfully installed 'SignalR 0.3.5'.
Successfully added 'Microsoft.Web.Infrastructure 1.0.0.0' to SignalRDemo.
Successfully added 'SignalR.Server 0.3.5' to SignalRDemo.
Successfully added 'SignalR.Js 0.3.5' to SignalRDemo.
Successfully added 'SignalR 0.3.5' to SignalRDemo.&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
Esta instalación incluye, además de algún elemento infraestructural, dos componentes de SignalR:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SignalR.Server&lt;/strong&gt;, que es la biblioteca de servidor principal para integrar en aplicaciones ASP.NET.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SignalR.Js&lt;/strong&gt;, la biblioteca Javascript necesaria para conectar desde cliente (páginas web) con el servidor.&lt;/li&gt;
&lt;/ul&gt;
Existen también otros clientes específicos para .NET, como &lt;strong&gt;SignalR.Client&lt;/strong&gt; (cliente genérico), &lt;strong&gt;SignalR.Client.Silverlight&lt;/strong&gt; (específico para SL), o &lt;strong&gt;SignalR.Client.WP7&lt;/strong&gt; (específico para Windows Phone 7), que podemos instalar de forma independiente. &lt;br /&gt;
&lt;br /&gt;
Además, tanto en Nuget como en el sitio web del producto podéis encontrar otros paquetes interesantes a los que vale la pena echar un vistazo, como &lt;strong&gt;SignalR.Sample&lt;/strong&gt;, un ejemplo completo de uso de este componente, &lt;strong&gt;SignalR.SelfHost&lt;/strong&gt;, que permite activar el servidor sin usar ASP.NET, o &lt;strong&gt;SignalR.Websockets&lt;/strong&gt;, un adaptador (o transporte, en argot SignalR) para usar Websockets para el mantenimiento de la conexión entre cliente y servidor.&lt;br /&gt;
&lt;br /&gt;
Observaréis que en todos los casos se trata de versiones muy preliminares pero que podemos ir probando y disfrutando desde ya, porque funcionan bastante bien. Podéis comprobarlo accediendo a &lt;a href="http://jabbr.net/"&gt;http://jabbr.net/&lt;/a&gt;, un chat implementado sobre SignalR donde&amp;nbsp;podréis encontrar charlando hasta a los mismísimos padres de la criatura.&amp;nbsp;:-)&lt;br /&gt;
&lt;br /&gt;
En el próximo post veremos cómo implementar clientes y servicios SignalR utilizando conexiones persistentes, el enfoque de menor nivel ofrecido por este fantástico componente.&lt;br /&gt;
&lt;br /&gt;
Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-7220179047086470305?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eoSFgZcDlpCnQFFBVuO4pbmkXEw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eoSFgZcDlpCnQFFBVuO4pbmkXEw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eoSFgZcDlpCnQFFBVuO4pbmkXEw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eoSFgZcDlpCnQFFBVuO4pbmkXEw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=KZMWKcZoslM:JwrgBf1apgM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=KZMWKcZoslM:JwrgBf1apgM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=KZMWKcZoslM:JwrgBf1apgM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=KZMWKcZoslM:JwrgBf1apgM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/KZMWKcZoslM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/7220179047086470305/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=7220179047086470305" title="3 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7220179047086470305?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7220179047086470305?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/KZMWKcZoslM/introduccion-signalr-i-conceptos.html" title="Introducción a SignalR (I): Conceptos básicos" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-nD6ITJOSkno/TxQj-U7Y4yI/AAAAAAAABuk/T2HeCKsE7HM/s72-c/image61.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/introduccion-signalr-i-conceptos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMMQXgzfCp7ImA9WhRVF00.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-9161969675533616767</id><published>2012-01-16T09:28:00.000+01:00</published><updated>2012-01-16T09:28:00.684+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-16T09:28:00.684+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 68</title><content type="html">&lt;a href="http://lh6.ggpht.com/-zzC6EA0NSks/TxMu2cZpg2I/AAAAAAAABuU/c1nOUXqd1B0/s1600-h/image7_thumb_thumb_thumb3.png"&gt;&lt;img align="right" alt="Enlaces interesantes" border="0" height="129" src="http://lh3.ggpht.com/-j3IS-VhBUnU/TxMu3CE7WfI/AAAAAAAABuc/kZa_femWmLE/image7_thumb_thumb_thumb_thumb.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes" width="172" /&gt;&lt;/a&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 9 al 15 de enero de 2012. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;
.Net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/kirillosenkov/archive/2012/01/10/datetime-utcnow-is-generally-preferable-to-datetime-now.aspx"&gt;&lt;strong&gt;DateTime.UtcNow is generally preferable to DateTime.Now&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Kirill Osenkov &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.blackwasp.co.uk/StaticFieldInitOrder.aspx"&gt;C# Static Field Initialisation Order&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;BlackWasp &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geekswithblogs.net/simonc/archive/2012/01/05/inside-the-concurrent-collections.aspx"&gt;&lt;strong&gt;Inside the Concurrent Collections&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simon Cooper &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blackrabbitcoder.net/archive/2012/01/05/c.net-little-wonders-the-datetime-tryparse-and-parseexact-methods.aspx"&gt;&lt;strong&gt;C#/.NET Little Wonders: The DateTime TryParse() and ParseExact() Methods&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;James Michael Hare &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Asp.net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://gregorsuttie.com/2012/01/12/attributerouting-for-mvc/"&gt;AttributeRouting for MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gregor Suttie &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://pfelix.wordpress.com/2012/01/11/the-new-net-httpclient-class/"&gt;The new .NET HttpClient class&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Pedro Félix&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.kirupa.com/html5/creating_printer_friendly_pages.htm"&gt;Creating Printer Friendly Pages&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Kirupa Chinnathambi &lt;/li&gt;
&lt;li&gt;&lt;a href="http://haacked.com/archive/2012/01/10/a-really-empty-asp-net-mvc-3-project-template.aspx"&gt;&lt;strong&gt;A Really Empty ASP.NET MVC 3 Project Template&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Phil Haack &lt;/li&gt;
&lt;li&gt;&lt;a href="http://teelahti.fi/blog/different-asp.net-mvc-master-page-for-authenticated-and-unauthenticated-users"&gt;&lt;strong&gt;Different ASP.NET MVC master page for authenticated and unauthenticated users&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Tero Teelahti &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/gperez/archive/2012/01/10/modernizr-ejemplo-pr-225-ctico-1-utilizando-placeholder.aspx"&gt;Modernizr–Ejemplo práctico 1 : Utilizando Placeholder&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gonzalo Pérez &lt;/li&gt;
&lt;li&gt;&lt;a href="http://codeclimber.net.nz/archive/2012/01/09/evolution-of-async-controller-asp-net-mvc.aspx"&gt;&lt;strong&gt;The evolution of asynchronous controllers in ASP.NET MVC&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simone Chiaretta &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jasoft.org/Blog/post/Plantillas-de-lado-cliente-con-JavaScript-191;Que-tecnologia-utilizar.aspx"&gt;&lt;strong&gt;Plantillas de lado cliente con JavaScript: ¿Qué tecnología utilizar?&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html"&gt;&lt;strong&gt;ASP.NET session hijacking with Google and ELMAH&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Troy Hunt &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Azure / Cloud&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.returngis.net/2012/01/node-js-windows-azure-que-es-realmente-node-js-por-donde-empiezo-creando-mi-web-server/"&gt;&lt;strong&gt;Node.js &amp;amp; Windows Azure – ¿Qué es realmente Node.js? ¿Por dónde empiezo? Creando mi Web server&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Gisela Torres &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.iis.net/port25-php/archive/2012/01/09/windows-azure-libraries-for-java-available-including-support-for-service-bus.aspx"&gt;Windows Azure Libraries for Java Available, including support for Service Bus&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ram Jeyaraman &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Data access&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2012/01/12/ef-4-3-beta-1-released.aspx"&gt;EF 4.3 Beta 1 Released&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;ADO.NET Team blog &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2012/01/12/ef-4-x-sql-federations.aspx"&gt;EF 4.X: Sql Federations&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Unai Zorrilla &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/01/12/comparativa-orm-lite-ef-y-ado-net.aspx#comments"&gt;Comparativa ORM-Lite, EF y ADO.NET&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Javier Torrecilla&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cheat.errtheblog.com/s/mongo"&gt;&lt;strong&gt;MongoDb cheat sheet&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Cheat Sheets &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.primaryobjects.com/CMS/Article137.aspx"&gt;&lt;strong&gt;MongoDb Enterprise Design with C# .NET, the Repository Pattern, and NoSQL&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Kory Becker &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/01/10/orm-lite-petapoco.aspx"&gt;[ORM-Lite] PetaPoco&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Javier Torrecilla &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/01/09/orm-lite-massive.aspx" title="[ORM-Lite] Massive"&gt;&lt;strong&gt;[ORM-Lite] Massive&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Javier Torrecilla &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Html/Css/Javascript&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.etnassoft.com/2012/01/12/el-valor-de-this-en-javascript-como-manejarlo-correctamente/"&gt;&lt;strong&gt;El valor de this en Javascript: cómo manejarlo correctamente&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Carlos Benítez &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.jqueryui.com/2012/01/jquery-ui-1-8-17/"&gt;&lt;strong&gt;jQuery UI 1.8.17 released&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Scott González &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/hh708752.aspx"&gt;Using HTML5 Canvas for Data Visualization&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Brandon Satrom &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.kirupa.com/html5/advanced_random_numbers_js.htm"&gt;Advanced Random Numbers in JS&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Kyle Delaney &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://nerdplusart.com/why-is-there-flash-in-the-html5-version-of-cut-the-rope"&gt;Why is there the Flash in the HTML5 version of Cut the Rope?&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Robby Ingebretsen &lt;/li&gt;
&lt;li&gt;&lt;a href="http://encosia.com/adding-your-own-callbacks-to-existing-javascript-functions/"&gt;&lt;strong&gt;Adding your own callbacks to existing JavaScript functions&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Dave Ward &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/ie/archive/2012/01/11/controlling-selection-with-css-user-select.aspx"&gt;Controlling Selection with CSS user-select&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;IE Blog&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://html5doctor.com/the-contenteditable-attribute/"&gt;The contenteditable attribute&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Jack Osborne &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.impressivewebs.com/textarea-auto-resize/"&gt;&lt;strong&gt;Textarea Auto Resize&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Louis Lazaris &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/esmsdn/archive/2012/01/03/aprende-html5-con-este-curso-gratis.aspx"&gt;Curso gratuito de HTML5&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;MSDN &lt;/li&gt;
&lt;li&gt;&lt;a href="http://freshbrewedcode.com/derekgreer/2012/01/08/solid-javascript-the-interface-segregation-principle/" title="Permanent Link to SOLID JavaScript- The Interface Segregation Principle"&gt;&lt;strong&gt;SOLID JavaScript- The Interface Segregation Principle&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Derek Greer &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://killdream.github.com/blog/2011/10/understanding-javascript-oop/index.html"&gt;Understanding JavaScript OOP&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Quildreen Motta &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.anieto2k.com/2012/01/08/speech-javascript-api-habla-con-las-paginas-web/"&gt;&lt;strong&gt;Speech Javascript API, habla con las páginas web&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Andrés Nieto &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Visual Studio/Complementos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeproject.com/KB/debug/Advanced_Debugging.aspx"&gt;Advanced Debugging in Visual Studio&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Pankaj Chamria &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Otros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.cuttherope.ie/" title="http://www.cuttherope.ie/"&gt;&lt;strong&gt;Cut the rope online&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sukria.net/fr/archives/2012/01/06/the-10-rules-of-the-pragmatic-programmer/"&gt;&lt;strong&gt;The 10 rules of the pragmatic programmer&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alexis Sukrieh &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lontivero/archive/2012/01/08/programar-no-es-tan-complicado.aspx"&gt;Programar no es tan complicado&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Lucas Ontivero &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-9161969675533616767?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8gK3rfTRLyLSkSWdA9vXFB6UZUs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8gK3rfTRLyLSkSWdA9vXFB6UZUs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8gK3rfTRLyLSkSWdA9vXFB6UZUs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8gK3rfTRLyLSkSWdA9vXFB6UZUs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=fv-6pcJMZJ8:U1zXIFw2EP0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=fv-6pcJMZJ8:U1zXIFw2EP0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=fv-6pcJMZJ8:U1zXIFw2EP0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=fv-6pcJMZJ8:U1zXIFw2EP0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/fv-6pcJMZJ8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/9161969675533616767/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=9161969675533616767" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/9161969675533616767?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/9161969675533616767?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/fv-6pcJMZJ8/enlaces-interesantes-68.html" title="Enlaces interesantes 68" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-j3IS-VhBUnU/TxMu3CE7WfI/AAAAAAAABuc/kZa_femWmLE/s72-c/image7_thumb_thumb_thumb_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/enlaces-interesantes-68.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEHSXs_eSp7ImA9WhRVEUU.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-2239867427828909298</id><published>2012-01-10T10:24:00.000+01:00</published><updated>2012-01-10T10:27:18.541+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-10T10:27:18.541+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desarrollo" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><category scheme="http://www.blogger.com/atom/ns#" term="consultas" /><category scheme="http://www.blogger.com/atom/ns#" term="trucos" /><title>Establecer el foco automáticamente, versión declarativa</title><content type="html">&lt;img align="right" alt="ASP.NET MVC" border="0" height="77" src="http://lh5.ggpht.com/-jgTyrW-fw8w/TuZBmb3t73I/AAAAAAAABso/DlIyZk4Euqs/ASPNETMVC2.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ASP.NET MVC" width="142" /&gt;Hace poco escribía un post en el que mostraba cómo se podía conseguir &lt;a href="http://www.variablenotfound.com/2011/12/aspnet-mvc-establecer-el-foco-en-un.html"&gt;establecer el foco inicialmente en un control de edición&lt;/a&gt;, algo que era posible con Webforms pero no directamente con las herramientas que ASP.NET MVC trae de fábrica.&lt;br /&gt;
&lt;br /&gt;
La solución propuesta consistía en introducir en la vista código de script para desplazar el foco hasta el control indicado mediante una llamada al helper &lt;code&gt;Html.SetFocusTo()&lt;/code&gt;, que implementábamos en el mismo post, aunque hay otras formas para conseguirlo.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Unos días después, un amigo de &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt; preguntaba en un &lt;a href="http://www.variablenotfound.com/2011/12/aspnet-mvc-establecer-el-foco-en-un.html?showComment=1324460046265#c2027359161527997766"&gt;comentario&lt;/a&gt; si no había una forma de conseguir lo mismo utilizando una sintaxis más declarativa, al estilo de la especificación de metadatos o validadores basados en atributos o &lt;em&gt;data annotations&lt;/em&gt;.&lt;br /&gt;
&lt;br /&gt;
En primer lugar he de decir que&amp;nbsp; no creo que sea muy conveniente hacerlo, puesto en casi todos los escenarios posicionar el foco en un elemento es pura presentación, no suele haber decisiones de negocio tras ello, y por tanto no es algo que debamos sacar de la Vista. Pero bueno, independientemente de eso, vamos a ver cómo podríamos conseguirlo.&lt;br /&gt;
&lt;br /&gt;
Una forma relativamente sencilla de hacerlo sería&lt;a href="http://www.variablenotfound.com/2011/12/imetadataaware-atributos-de-metadatos.html"&gt; utilizando atributos de metadatos personalizados&lt;/a&gt; de forma muy similar al ejemplo que vimos también en un post anterior.&lt;br /&gt;
&lt;br /&gt;
Lo primero que necesitamos es definir un atributo que implemente &lt;code&gt;IMetadataAware&lt;/code&gt;, lo que indica que incluye información sobre metadatos, y aprovechar el método &lt;code&gt;OnMetadataCreated()&lt;/code&gt; para introducir en la colección de metadatos adicionales una señal que permita más adelante detectar la propiedad a “enfocar”:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;FocusedAttribute&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;Attribute&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;IMetadataAware&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;const&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; MetadataKey = &lt;span style="color: #a31515;"&gt;"Focused"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnMetadataCreated(&lt;span style="color: #2b91af;"&gt;ModelMetadata&lt;/span&gt; metadata)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metadata.AdditionalValues[MetadataKey] = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
De esta forma, para activar el foco inicialmente sobre el editor de una propiedad concreta, simplemente deberíamos marcarla con el atributo &lt;code&gt;[Focused]&lt;/code&gt;, como se muestra en el código siguiente:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Focused&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Email { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Phone { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Fax { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Una vez finalizados los preparativos, tenemos que ver cómo implementarlo en la vista. Lo más sencillo en este caso sería crear el helper &lt;code&gt;Html.Autofocus()&lt;/code&gt;, que será encargado de localizar la propiedad con el atributo &lt;code&gt;[Focused]&lt;/code&gt; y generar sobre la vista el script que mueva el foco a la misma:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlExtensions&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt; Autofocus(&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlHelper&lt;/span&gt; html)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; template = html.ViewData.TemplateInfo;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; focusedProperty = 
             (&lt;span style="color: blue;"&gt;from&lt;/span&gt; property &lt;span style="color: blue;"&gt;in&lt;/span&gt; html.ViewData.ModelMetadata.Properties
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;where&lt;/span&gt; property.AdditionalValues.Any(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a =&amp;gt; a.Key == &lt;span style="color: #2b91af;"&gt;FocusedAttribute&lt;/span&gt;.MetadataKey &amp;amp;&amp;amp; (&lt;span style="color: blue;"&gt;bool&lt;/span&gt;) a.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;select&lt;/span&gt; template.GetFullHtmlFieldId(property.PropertyName)
             ).FirstOrDefault();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (focusedProperty != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; createAutofocusScript(focusedProperty);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;null&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt; createAutofocusScript(&lt;span style="color: blue;"&gt;string&lt;/span&gt; focusedProperty)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; script = &lt;span style="color: #a31515;"&gt;"&amp;lt;script type='text/javascript'&amp;gt;"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"$(function() { $('#"&lt;/span&gt; + focusedProperty + &lt;span style="color: #a31515;"&gt;"').focus(); });"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"&amp;lt;/script&amp;gt;"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt;.Create(script);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
Por último, basta con introducir en la vista la siguiente llamada. O mejor aún, si queremos que esta funcionalidad esté activa en todas las vistas, podemos añadirla al final del Layout que estemos empleando para ellas:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-attachment: scroll; background-image: none; background-repeat: repeat;"&gt;&lt;span style="background-color: yellow;"&gt;@&lt;/span&gt;&lt;/span&gt;Html.Autofocus()&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Hay que tener en cuenta que nada impide que el atributo &lt;code&gt;Focused&lt;/code&gt; sea empleado en más de una propiedad, en cuyo caso el foco se establecerá en la primera ocurrencia localizada. Esto se podría evitar llevando el atributo a nivel de clase e indicando como parámetro el valor de la propiedad (algo así como &lt;code&gt;[DefaultProperty("Name")]&lt;/code&gt; sobre la propia entidad). En el proyecto de demostración podréis encontrar también esta implementación.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://skydrive.live.com/redir.aspx?cid=c3a43a99b617d787&amp;amp;resid=C3A43A99B617D787!276&amp;amp;parid=C3A43A99B617D787!244&amp;amp;authkey=!AOOz8EFf3UOm_tw"&gt;Descargar proyecto de demostración (VS2010+MVC 3) desde Skydrive&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-2239867427828909298?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xWqdIYWHhcOXA0rJic5e3wrJ6kQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xWqdIYWHhcOXA0rJic5e3wrJ6kQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xWqdIYWHhcOXA0rJic5e3wrJ6kQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xWqdIYWHhcOXA0rJic5e3wrJ6kQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=3RpRJt8GIsY:oyX1jFiopf8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=3RpRJt8GIsY:oyX1jFiopf8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=3RpRJt8GIsY:oyX1jFiopf8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=3RpRJt8GIsY:oyX1jFiopf8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/3RpRJt8GIsY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/2239867427828909298/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=2239867427828909298" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/2239867427828909298?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/2239867427828909298?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/3RpRJt8GIsY/establecer-el-foco-por-defecto-version.html" title="Establecer el foco automáticamente, versión declarativa" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-jgTyrW-fw8w/TuZBmb3t73I/AAAAAAAABso/DlIyZk4Euqs/s72-c/ASPNETMVC2.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/establecer-el-foco-por-defecto-version.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQNRn4zeyp7ImA9WhRVEU4.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-4659903764163834149</id><published>2012-01-09T09:30:00.000+01:00</published><updated>2012-01-09T20:46:37.083+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-09T20:46:37.083+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 67</title><content type="html">&lt;a href="http://lh6.ggpht.com/-9hoAPQEslk8/Twqa343EjzI/AAAAAAAABuE/iRo3ZjlylCI/s1600-h/image7_thumb_thumb2.png"&gt;&lt;img align="right" alt="Enlaces interesantes" border="0" height="129" src="http://lh3.ggpht.com/-TnHwJPBxXIw/Twqa49716LI/AAAAAAAABuM/RfEWBHubIuE/image7_thumb_thumb_thumb.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes" width="172" /&gt;&lt;/a&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; en la primera semana del año 2012. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;

.Net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/etomas/archive/2012/01/05/c-b-225-sico-eventos.aspx"&gt;C# Básico: Eventos&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Eduard Tomás &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/vancem/archive/2011/12/28/publication-of-the-perfview-performance-analysis-tool.aspx"&gt;PerfView performance analysis tool&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Vance Morrison &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jorge/archive/2012/01/04/resumen-de-las-versiones-de-net.aspx"&gt;Resumen de las versiones de .NET&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jorge Serrano &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://visualstudiomagazine.com/articles/2012/01/01/tdd-generate-from-usage-and-continuous-testing.aspx"&gt;Test-Driven Development, Generate from Usage and Continuous Testing&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Peter Vogel &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Asp.net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://afana.me/post/paging-sorting-and-searching-ef-cf-and-mvc.aspx"&gt;&lt;strong&gt;Paging, sorting, and searching using EF Code first and MVC 3&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Nadeem Afana &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://visualstudiomagazine.com/articles/2012/01/01/web-forms-with-html5.aspx"&gt;Web Forms with HTML5&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Mark Michaelis &lt;/li&gt;
&lt;li&gt;&lt;a href="http://leoncullens.nl/post/2011/12/24/Essential-guide-to-ASPNET-MVC3-performance.aspx" title="Essential guide to ASP.NET MVC3 performance"&gt;&lt;strong&gt;Essential guide to ASP.NET MVC3 performance&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Leon Cullens &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.koalite.com/2012/01/web-scraping-con-html-agility-pack/"&gt;&lt;strong&gt;Web Scraping con HTML Agility Pack&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Juan María Hernández &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.mikesdotnetting.com/Article/186/Using-The-Themes-Helper-In-Razor-Web-Pages"&gt;Using The Themes Helper In Razor Web Pages&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Mike Brind &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Data access&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/01/03/dapper-dot-net.aspx"&gt;Dapper Dot Net&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Javier Torrecilla &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Html/Css/Javascript&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://jsutility.pjoneil.net/"&gt;Compresor, Ofuscador, Minificador, Validador de JavaScript&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Patrick J. O'Neil (vía @chalalo) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/"&gt;Profiling CSS for fun and profit. Optimization notes.&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Juriy Zaytsev &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/"&gt;Cross Browser HTML5 Progress Bars In Depth&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Zoltan Hawryluk &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.kirupa.com/html5/hashtables_vs_arrays.htm"&gt;Hashtables vs. Arrays&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Kirupa Chinnathambi &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-the-module-pattern-part-3/"&gt;&lt;strong&gt;JavaScript for C# developers: the Module Pattern (part 3)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Julian M Bucknall &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.anieto2k.com/2012/01/05/battery-status-api-controla-la-carga-de-la-bateria-de-tus-usuarios-con-javascript/" title="Enlace a Battery Status API, controla la carga de la batería de tus usuarios con Javascript"&gt;&lt;strong&gt;Battery Status API, controla la carga de la batería de tus usuarios con Javascript&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Andrés Nieto &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-the-module-pattern-part-2/"&gt;&lt;strong&gt;JavaScript for C# developers: the Module Pattern (part 2)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Julian M Bucknall &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Visual Studio/Complementos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://visualstudiomagazine.com/articles/2012/01/01/visual-basic-improvements-in-visual-studio-11.aspx"&gt;&lt;strong&gt;Visual Basic Improvements in Visual Studio 11&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Joe Kunk &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.jetbrains.com/dotnet/2012/01/optimizing-assembly-references-with-resharper-61/"&gt;Optimizing Assembly References with ReSharper 6.1&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;by Jura Gorohovsky &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Otros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://ajnt.wordpress.com/2012/01/04/windows-7-god-mode-gives-lots-more-options/"&gt;Windows 7 “God Mode” gives lots more options&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Andy Twine &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.brentozar.com/archive/2012/01/notes-on-scalability/"&gt;Notes on Scalability&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jeremiah Peschka &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.genbeta.com/windows/microsoft-da-detalles-acerca-del-reset-y-el-refresh-de-windows-8"&gt;Microsoft da detalles acerca del "reset" y el "refresh" de Windows 8&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Manu Mateos &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://hadihariri.com/2012/01/04/errors-handle-with-care/"&gt;Errors: Handle with care&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Hadi Hariri &lt;/li&gt;
&lt;li&gt;&lt;a href="http://leoncullens.nl/post/2012/01/01/8-Things-clients-need-to-learn-about-software-development.aspx" title="8 Things clients need to learn about software development"&gt;&lt;strong&gt;8 Things clients need to learn about software development&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Leon Cullens &lt;/li&gt;
&lt;li&gt;&lt;a href="http://jmalarcon.es/post/Artesanos-del-conocimiento.aspx" title="Artesanos del conocimiento"&gt;&lt;strong&gt;Artesanos del conocimiento&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://pulkitarora.wordpress.com/2011/03/12/91-ways-to-become-the-coolest-developer-in-the-world/"&gt;91 Ways to become the Coolest Developer in the World&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Pulkit Arora &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-4659903764163834149?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WVOTVLpU0dt_EaJ_YfXOiAoSstc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WVOTVLpU0dt_EaJ_YfXOiAoSstc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WVOTVLpU0dt_EaJ_YfXOiAoSstc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WVOTVLpU0dt_EaJ_YfXOiAoSstc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=2AkHp_bqI78:6s5ucACneuo:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=2AkHp_bqI78:6s5ucACneuo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=2AkHp_bqI78:6s5ucACneuo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=2AkHp_bqI78:6s5ucACneuo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/2AkHp_bqI78" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/4659903764163834149/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=4659903764163834149" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/4659903764163834149?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/4659903764163834149?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/2AkHp_bqI78/enlaces-interesantes-67.html" title="Enlaces interesantes 67" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-TnHwJPBxXIw/Twqa49716LI/AAAAAAAABuM/RfEWBHubIuE/s72-c/image7_thumb_thumb_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/enlaces-interesantes-67.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QDRHg7fip7ImA9WhRWFkQ.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-5333824124915026829</id><published>2012-01-04T09:06:00.000+01:00</published><updated>2012-01-04T17:42:55.606+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-04T17:42:55.606+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 66</title><content type="html">&lt;a href="http://lh5.ggpht.com/-a_y4n1_Qxcw/TwLhhKmmn-I/AAAAAAAABt0/WcP_jZ7W0PE/s1600-h/image7_thumb3.png"&gt;&lt;img align="right" alt="Enlaces interesantes" border="0" height="129" src="http://lh6.ggpht.com/-RT3sfxH3GUY/TwLhh-N0PII/AAAAAAAABt8/dKASPj3OHOM/image7_thumb_thumb.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes" width="172" /&gt;&lt;/a&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; en la última semana del año 2011. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;

.Net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/29/the-concept-of-async-await.aspx"&gt;The concept of async/await&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Buaya Eshet &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;December Headline: C++ about to be dethroned by C#&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;TIOBE (vía @lluisfranco) &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Asp.net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.eggheadcafe.com/tutorials/asp-net/e653f028-01fb-4d0e-843b-058deae562a2/eight-different-ways-to-transfer-data-from-one-page-to-another-page.aspx"&gt;Eight Different Ways to Transfer Data from One Page to Another Page&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Peter Bromberg &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/12/28/asp-net-security-update-shipping-thursday-dec-29th.aspx"&gt;ASP.NET Security Update Shipping Thursday, Dec 29th&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Scott Guthrie (vía @CampusMVP) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://desarrolloweb.com/articulos/validaciones-aspnet-mvc-donet.html"&gt;Validaciones en ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Eduard Tomás &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geekstuff.cc/2011/12/25/client-side-routing-with-asp-net-mvc/"&gt;&lt;strong&gt;Client-side routing with ASP.NET MVC&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Geek Stuff &lt;/li&gt;
&lt;li&gt;&lt;a href="http://dailydotnettips.com/2011/12/25/control-level-request-validation-in-asp-net-4-5/"&gt;&lt;strong&gt;Control level request validation in ASP.NET 4.5&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Abhijit Jana &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeguru.com/csharp/.net/net_asp/article.php/c19797/Dealing-with-Profile-Access-in-ASPNET-MVC-Applications.htm"&gt;Dealing with Profile Access in ASP.NET MVC Applications&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Bipin Joshi &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=780"&gt;ASP.NET MVC 3 Real Time Collaborative Apps with SignalR&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Sumit Maitra &lt;/li&gt;
&lt;li&gt;&lt;a href="http://oscarsotorrio.com/post/2011/12/24/Implementar-un-sitio-web-privado-con-ASPNET-MVC.aspx" title="Implementar un sitio web privado con ASP.NET MVC"&gt;&lt;strong&gt;Implementar un sitio web privado con ASP.NET MVC&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Óscar Sotorrío &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Azure / Cloud&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://debugmode.net/2011/12/31/sql-azure-to-developers-some-basic-concepts/"&gt;SQL Azure to Developers: Some Basic Concepts&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Dhananjay Kumar &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.returngis.net/2011/12/modificar-el-tiempo-de-vida-del-token-proporcionado-por-windows-azure-appfabric-access-control/"&gt;&lt;strong&gt;Modificar el tiempo de vida del token proporcionado por Windows Azure AppFabric Access Control&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Gisela Torres &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.returngis.net/2011/12/aumentar-el-timeout-en-las-operaciones-al-servicio-de-blobs-de-windows-azure-storage/"&gt;&lt;strong&gt;Aumentar el timeout en las operaciones al servicio de blobs de Windows Azure Storage&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Gisela Torres &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.returngis.net/2011/12/aumentar-el-tiempo-de-invisibilidad-o-el-contenido-de-un-mensaje-en-windows-azure-storage-queues/"&gt;&lt;strong&gt;Aumentar el tiempo de invisibilidad o el contenido de un mensaje en Windows Azure Storage Queues&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Gisela Torres &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Data access&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/microsoft_press/archive/2011/12/29/dino-esposito-the-o-rm-and-the-chicken-egg-dilemma.aspx"&gt;The O/RM and the chicken/egg dilemma&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Dino Esposito &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2011/12/30/lanzamiento-oficial-driver-oracle-para-entity-framework.aspx"&gt;Lanzamiento Oficial Driver Oracle para Entity Framework&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Javier Torrecilla &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Html/Css/Javascript&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.moretechtips.net/2011/12/22-most-popular-jquery-plugins-of-2011.html"&gt;&lt;strong&gt;22 Most Popular jQuery Plugins of 2011&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;More tech tips &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/gilf/archive/2011/12/29/the-async-and-defer-script-attributes-in-html5.aspx"&gt;The async and defer Script Attributes in HTML5&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gil Fink &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-the-module-pattern-part-1/"&gt;&lt;strong&gt;JavaScript for C# developers: the Module Pattern (part 1)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Julian M Bucknall &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2011/12/28/working-with-the-javascript-this-keyword.aspx"&gt;Working with the JavaScript “this” Keyword&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Dan Wahlin &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Visual Studio/Complementos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.jetbrains.com/dotnet/2011/12/resharper-61-improvements-in-intellisense-options/"&gt;ReSharper 6.1: Improvements in IntelliSense Options&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Hadi Hariri &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=781"&gt;Packaging a JavaScript Library with Nuget&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Sumit Maitra &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;

Otros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/davidjrh/archive/2011/12/28/tip-un-huevo-de-pascua-llamado-dnndev-me.aspx"&gt;[Tip] Un huevo de pascua llamado “dnndev.me”&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;David Rodríguez &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-5333824124915026829?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/o2mskm0zvXVbJFB8NnWmELxgleM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/o2mskm0zvXVbJFB8NnWmELxgleM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/o2mskm0zvXVbJFB8NnWmELxgleM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/o2mskm0zvXVbJFB8NnWmELxgleM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=tjw7Y0JYpLA:q8e7ESlPRAs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=tjw7Y0JYpLA:q8e7ESlPRAs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=tjw7Y0JYpLA:q8e7ESlPRAs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=tjw7Y0JYpLA:q8e7ESlPRAs:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/tjw7Y0JYpLA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/5333824124915026829/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=5333824124915026829" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/5333824124915026829?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/5333824124915026829?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/tjw7Y0JYpLA/enlaces-interesantes-66.html" title="Enlaces interesantes 66" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-RT3sfxH3GUY/TwLhh-N0PII/AAAAAAAABt8/dKASPj3OHOM/s72-c/image7_thumb_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/enlaces-interesantes-66.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4EQnw8eip7ImA9WhRWFkw.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-1290173615239569401</id><published>2012-01-03T11:37:00.000+01:00</published><updated>2012-01-03T19:21:43.272+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-03T19:21:43.272+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="recomendaciones" /><category scheme="http://www.blogger.com/atom/ns#" term="variablenotfound.com" /><category scheme="http://www.blogger.com/atom/ns#" term="blogging" /><category scheme="http://www.blogger.com/atom/ns#" term="resumen" /><title>Top posts 2011 en Variable not found</title><content type="html">&lt;img align="right" alt="image" border="0" height="114" src="http://lh5.ggpht.com/-7nh1agzXULE/TvxlVaADipI/AAAAAAAABtc/DROeeePCLvs/image%25255B7%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="147" /&gt;&lt;br /&gt;
Las tradiciones están para cumplirlas. Y casi desde el principio de los tiempos, el primer artículo del año está reservado a hacer un análisis retrospectivo y ver qué posts son los que más han llamado vuestra atención durante los 365 días que hemos dejado atrás, así que ya sabéis lo que toca ahora ;-)&lt;br /&gt;
&lt;br /&gt;
Pero antes de nada, aprovechando la inauguración oficial del 2012 en el blog, &lt;strong&gt;desearos a todos un feliz año 2012&lt;/strong&gt;, y que podáis disfrutarlo con salud, buena compañía, y prosperidad.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Como en otras ocasiones, vamos a distinguir entre los artículos publicados en 2011 y los escritos años anteriores, que forman parte de los “clásicos” de &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt; y siguen atrayendo una gran cantidad de visitantes.&lt;br /&gt;
&lt;h3&gt;




La cosecha de 2011&lt;/h3&gt;
El post más visitado del año, a una distancia abismal del que le sigue, es la &lt;strong&gt;&lt;a href="http://www.variablenotfound.com/2011/10/el-tao-de-la-programacion.html"&gt;traducción autorizada del mini-libro “El Tao de la programación”&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;. Obviamente el mérito no es mío, sino del gran &lt;a href="http://www.geoffreyjames.com/"&gt;Geoffrey James&lt;/a&gt;, que ya en el año 1987 supo reflejar verdades universales sobre el desarrollo de software usando un tono místico divertidísimo.&lt;br /&gt;
&lt;br /&gt;
En el segundo puesto encontramos el inicio de la serie “&lt;strong&gt;&lt;a href="http://www.variablenotfound.com/2011/02/webgrid-en-mvc-3-paso-paso.html"&gt;Webgrid en MVC 3, paso a paso&lt;/a&gt;&lt;/strong&gt;”, una descripción creo que bastante detallada del helper WebGrid que nos llegó con la tercera versión de ASP.NET MVC.&lt;br /&gt;
&lt;br /&gt;
En el puesto número tres, el post “&lt;a href="http://www.variablenotfound.com/2011/01/libro-adonet-entity-framework-40.html"&gt;&lt;strong&gt;Libro: ADO.NET Entity Framework 4.0. Aplicaciones y servicios centrados en datos&lt;/strong&gt;&lt;/a&gt;”, una reseña del magnífico libro del maestro Unai Zorrilla, que demuestra el interés que esta tecnología ha suscitado en el año. Decir que a día de hoy existe una &lt;a href="http://www.campusmvp.com/catalogo/Product-ADO.NET-Entity-Framework-4.1---Aplicaciones-y-servicios-centrados-en-datos_110.aspx"&gt;versión actualizada del libro a la versión 4.1&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
La cuarta y quinta posición del ranking de lo más leído en 2011 las ocupan, respectivamente, las siguientes partes de la serie sobre el helper WebGrid, “&lt;a href="http://www.variablenotfound.com/2011/02/webgrid-en-mvc-3-paso-paso-y-ii.html"&gt;&lt;strong&gt;WebGrid en MVC 3, paso a paso (y II)&lt;/strong&gt;&lt;/a&gt;” y “&lt;a href="http://www.variablenotfound.com/2011/02/webgrid-en-modo-ajax-con-mvc-3.html" title="WebGrid en modo Ajax con MVC 3"&gt;&lt;strong&gt;WebGrid en modo Ajax con MVC 3&lt;/strong&gt;&lt;/a&gt;”. El que este trío de posts se encuentren en los cinco primeros puestos sólo pone de manifiesto una cosa: las rejillas de datos siguen siendo las estrellas de nuestras aplicaciones ;-)&lt;br /&gt;
&lt;br /&gt;
En sexto lugar, tenemos el post “&lt;a href="http://www.variablenotfound.com/2011/02/serializacion-y-deserializacion-json-en.html" title="Serialización y deserialización Json en MVC 3"&gt;&lt;strong&gt;Serialización y deserialización Json en MVC 3&lt;/strong&gt;&lt;/a&gt;”, donde se mostraba el uso de los nuevos helpers de serialización disponibles en el espacio de nombres &lt;code&gt;System.Web.Helpers&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
El séptimo lugar lo ocupa una reflexión sobre usabilidad e interfaces de usuario, a raíz del asombroso formulario principal de una conocida aplicación: “&lt;a href="http://www.variablenotfound.com/2011/03/lo-que-ocurre-cuando-desarrolladores.html" title="Lo que ocurre cuando desarrolladores diseñan interfaces de usuario (II)"&gt;&lt;strong&gt;Lo que ocurre cuando desarrolladores diseñan interfaces de usuario (II)&lt;/strong&gt;&lt;/a&gt;”.&lt;br /&gt;
&lt;br /&gt;
Ya en octavo puesto está el post “&lt;a href="http://www.variablenotfound.com/2011/09/aspnet-mvc-4-developer-preview-un.html"&gt;&lt;strong&gt;ASP.NET MVC 4 Developer Preview: un primer vistazo&lt;/strong&gt;&lt;/a&gt;”, un repaso a las novedades disponibles en la preview de la nueva versión del framework MVC.&lt;br /&gt;
&lt;br /&gt;
Otro post que ha interesado es “&lt;a href="http://www.variablenotfound.com/2011/05/glimpse-simplemente-imprescindible.html" title="Glimpse- simplemente imprescindible"&gt;&lt;strong&gt;Glimpse- simplemente imprescindible&lt;/strong&gt;&lt;/a&gt;”, en novena posición, donde se describía esta interesante herramienta de depuración para ASP.NET.&lt;br /&gt;
&lt;br /&gt;
Y en el puesto número diez, el post “&lt;a href="http://www.variablenotfound.com/2011/04/aspnet-mvc-3-tools-update.html" title="ASP.NET MVC 3 Tools update"&gt;&lt;strong&gt;ASP.NET MVC 3 Tools update&lt;/strong&gt;&lt;/a&gt;”, que da un repaso a las novedades que fueron incluidas en la actualización de herramientas del framework MVC.&lt;br /&gt;
&lt;h3&gt;




Cosechas anteriores a 2011&lt;/h3&gt;
&lt;img align="right" alt="Buena cosecha, la de otros años" border="0" height="134" src="http://lh4.ggpht.com/-bO7S-fj4gb4/TvxlWg_xHhI/AAAAAAAABtk/jUJxT6N6_RE/image%25255B12%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Buena cosecha, la de otros años" width="179" /&gt;Estos artículos fueron escritos en años anteriores a 2011, pero en muchos casos siguen siendo válidos, y de hecho, atraen a una gran cantidad de visitas al blog.&lt;br /&gt;
&lt;br /&gt;
Comenzamos por un clásico de los de toda la vida: “&lt;a href="http://www.variablenotfound.com/2010/05/aspnet-mvc-2-quince-cuestiones-que.html" title="ASP.NET MVC 2- Quince cuestiones que deberías conocer"&gt;&lt;strong&gt;ASP.NET MVC 2- Quince cuestiones que deberías conocer&lt;/strong&gt;&lt;/a&gt;”, que aunque se refiere a la segunda versión del framework, la mayoría de cuestiones siguen siendo válidas. A ver si este año se tercia y publico una nueva edición actualizada ;-)&lt;br /&gt;
&lt;br /&gt;
En segundo lugar nos vamos a 2009, cuando en el post “&lt;a href="http://www.variablenotfound.com/2009/10/jqgrid-grids-espectaculares-para-aspnet.html" title="jqGrid- Grids espectaculares para ASP.NET MVC, paso a paso"&gt;&lt;strong&gt;jqGrid - Grids espectaculares para ASP.NET MVC, paso a paso&lt;/strong&gt;&lt;/a&gt;” describíamos detalladamente el uso de este fantástico plugin para la creación de rejillas de datos.&lt;br /&gt;
&lt;br /&gt;
En tercer lugar, tenemos la célebre recopilación “&lt;a href="http://www.variablenotfound.com/2008/02/101-citas-clebres-del-mundo-de-la.html" title="101 citas célebres del mundo de la informática"&gt;&lt;strong&gt;101 citas célebres del mundo de la informática&lt;/strong&gt;&lt;/a&gt;”, que fue el inicio de una de las series que más popularidad han dado al blog desde su comienzo.&lt;br /&gt;
&lt;br /&gt;
A continuación encontramos un artículo de 2008, “&lt;a href="http://www.variablenotfound.com/2008/01/32-tcnicas-de-produccin-de-ideas.html" title="32 técnicas de producción de ideas"&gt;&lt;strong&gt;32 técnicas de producción de ideas&lt;/strong&gt;&lt;/a&gt;”, en el que se resumen técnicas que favorecen la creatividad y generación de ideas, y que sigue atrayendo mucho tráfico al blog.&lt;br /&gt;
&lt;br /&gt;
En quinto lugar, un post de 2007 (!) que muestra cómo crear bordes redondeados utilizando una famosa biblioteca de la época: “&lt;a href="http://www.variablenotfound.com/2007/09/bordes-redondeados-en-webs-sin-esfuerzo.html" title="Bordes redondeados en webs (sin esfuerzo) con Nifty Corners Cube"&gt;&lt;strong&gt;Bordes redondeados en webs (sin esfuerzo) con Nifty Corners Cube&lt;/strong&gt;&lt;/a&gt;”. &lt;br /&gt;
&lt;br /&gt;
El sexto lugar pone de manifiesto que todavía XP y Vista están muy vivos, pues corresponde al artículo “&lt;a href="http://www.variablenotfound.com/2010/01/acceder-al-contenido-de-un-vhd-desde.html" title="Vista"&gt;&lt;strong&gt;Acceder al contenido de un .vhd desde Windows XP/Vista&lt;/strong&gt;&lt;/a&gt;”.&lt;br /&gt;
&lt;br /&gt;
En séptima posición, un artículo de 2007, “&lt;a href="http://www.variablenotfound.com/2007/05/llamar-mtodos-estticos-con-aspnet-ajax.html" title="Llamar a métodos estáticos con ASP.NET Ajax"&gt;&lt;strong&gt;Llamar a métodos estáticos con ASP.NET Ajax&lt;/strong&gt;&lt;/a&gt;”, un artículo que explora el uso de page methods como fórmula de comunicación asíncrona entre cliente y servidor.&lt;br /&gt;
&lt;br /&gt;
Otra &lt;em&gt;joya&lt;/em&gt; de 2007 para el octavo puesto: “&lt;a href="http://www.variablenotfound.com/2007/11/evitar-el-postback-al-pulsar-un-botn-en.html" title="Evitar el postback al pulsar un botón en ASP.Net"&gt;&lt;strong&gt;Evitar el postback al pulsar un botón en ASP.Net&lt;/strong&gt;&lt;/a&gt;”, donde se describe algunas fórmulas para impedir que se realice un envío al servidor cuando se pulsa un botón de formulario en webforms.&lt;br /&gt;
&lt;br /&gt;
En el puesto número nueve, un post escrito en 2010 que muestra, paso a paso, cómo utilizar el plugin Datepicker de jQuery para editar fechas en aplicaciones MVC: “&lt;a href="http://www.variablenotfound.com/2010/06/edicion-elegante-de-fechas-con-jquery.html" title="Edición elegante de fechas con jQuery Datepicker y MVC, paso a paso"&gt;&lt;strong&gt;Edición elegante de fechas con jQuery Datepicker y MVC, paso a paso&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;”.&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Por último, un clásico humorístico: “&lt;a href="http://www.variablenotfound.com/2010/05/consejos-imprescindibles-por-si-algo.html" title="Consejos imprescindibles por si algo falla"&gt;&lt;strong&gt;Consejos imprescindibles por si algo falla&lt;/strong&gt;&lt;/a&gt;”, un compendio de barbaridades a tener en cuenta para responder cuando nuestras aplicaciones se comporten de forma no esperada. Sin duda, un manual&amp;nbsp;fundamental para todo desarrollador&amp;nbsp; ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span style="font-size: small;"&gt;¡Feliz 2012!&lt;/span&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-1290173615239569401?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PbyIPNF9cfD3BWdVv8PrQLsKeSc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PbyIPNF9cfD3BWdVv8PrQLsKeSc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PbyIPNF9cfD3BWdVv8PrQLsKeSc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PbyIPNF9cfD3BWdVv8PrQLsKeSc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=wX4WOE9gwWY:9iE2zNn9KVs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=wX4WOE9gwWY:9iE2zNn9KVs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=wX4WOE9gwWY:9iE2zNn9KVs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=wX4WOE9gwWY:9iE2zNn9KVs:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/wX4WOE9gwWY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/1290173615239569401/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=1290173615239569401" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/1290173615239569401?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/1290173615239569401?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/wX4WOE9gwWY/top-posts-2011-en-variable-not-found.html" title="Top posts 2011 en Variable not found" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-7nh1agzXULE/TvxlVaADipI/AAAAAAAABtc/DROeeePCLvs/s72-c/image%25255B7%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2012/01/top-posts-2011-en-variable-not-found.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cBSX8-eSp7ImA9WhRWEk4.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-294681660705501230</id><published>2011-12-28T01:31:00.000+01:00</published><updated>2011-12-30T09:50:58.151+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-30T09:50:58.151+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="novedades" /><category scheme="http://www.blogger.com/atom/ns#" term="azure" /><category scheme="http://www.blogger.com/atom/ns#" term="inocentadas" /><category scheme="http://www.blogger.com/atom/ns#" term="servicios on-line" /><title>Adzure, la nube gratuita soportada por publicidad</title><content type="html">&lt;iframe allowtransparency="true" frameborder="0" id="twttrHubFrame" name="twttrHubFrame" scrolling="no" src="http://platform.twitter.com/widgets/hub.1324331373.html" style="height: 10px; position: absolute; top: -9999em; width: 10px;" tabindex="0"&gt;&lt;/iframe&gt;Microsoft es una compañía que nos tiene acostumbrados a giros extraños en sus políticas de comercialización y distribución de productos, y está claro que la nube no iba a permanecer ajena a ellos.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="right" alt="Windows Adzure" border="0" height="132" src="http://lh5.ggpht.com/-NlqiGNTEfOU/TuNcVXHUidI/AAAAAAAABsQ/dEoPlwFhlAU/image7%25255B1%25255D.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Windows Adzure" width="273" /&gt;Hace un par de días, ante el asombro de los presentes, Fred Swarm (cloud manager para la región EMEA) anunció la próxima apertura de &lt;strong&gt;Adzure, la edición gratuita del servicio Windows Azure soportada por publicidad&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Esto supone una auténtica revolución en el mundo de los servicios en la nube, que pasan del tradicional enfoque &lt;em&gt;pay-per-use&lt;/em&gt; hacia un modelo de negocio basado en los ingresos publicitarios. Es decir, &lt;strong&gt;serán los anunciantes los que soportarán los costes&lt;/strong&gt; de mantener en funcionamiento los roles e instancias de nuestras aplicaciones en la nube, la ocupación en disco, transferencia, uso de CDN, etc., sólo a cambio de que dejemos que se inserten anuncios publicitarios en determinados puntos de nuestros sistemas.&lt;br /&gt;
&lt;br /&gt;
A cambio, no tendremos restricción alguna en cuanto al número de procesadores, memoria, ni ocupación de la infraestructura del gigante de Redmond. &lt;strong&gt;Podemos utilizar todos los recursos que necesitemos&lt;/strong&gt;, y de hecho, se anima a que así sea: si una aplicación web debe escalar de forma brutal es porque tiene muchos visitantes… y visitantes es igual a impactos publicitarios, por lo que sería el escenario ideal para todos.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="right" alt="Adzure insertando publicidad en el interior de imágenes" border="0" height="215" src="http://lh6.ggpht.com/-rbWk4hExvvQ/TuNcWJA6xrI/AAAAAAAABsY/iywaUGfokXk/image7.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Adzure insertando publicidad en el interior de imágenes" width="256" /&gt;Una de las cosas más curiosas de este servicio es precisamente que la inserción de la publicidad se realizará de forma automática, los desarrolladores no tendremos que hacer nada al respecto: simplemente, &lt;b&gt;los anuncios aparecerán en puntos donde la plataforma considere oportuno&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
Esto es posible gracias a la nueva &lt;strong&gt;tecnología &lt;em&gt;AdInsight®&lt;/em&gt;&lt;/strong&gt;, que se encarga de analizar nuestro software una vez lo hemos desplegado en Adzure e inyectar en ellos la lógica de generación de anuncios publicitarios. Está claro que este automatismo a veces puede provocar pequeñas intrusiones como la que veis en la captura de pantalla adjunta, pero estaréis de acuerdo en que es un precio bastante razonable teniendo en cuenta el valor y potencia de la infraestructura que estamos usando de forma gratuita :-)&lt;br /&gt;
&lt;br /&gt;
Según se desprende del documento de &lt;a href="http://technet.microsoft.com/ja-jp/library/ee783542(v=ws.10).aspx"&gt;notas de la revisión&lt;/a&gt;, existen tres únicos puntos de inserción publicitaria automática:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;las páginas web generadas por un WebRole &lt;em&gt;podrán ser modificadas&lt;/em&gt; de forma automática para incluirle código de script para la generación de anuncios contextuales.&lt;/li&gt;
&lt;li&gt;el servicio de almacenamiento blob para contenidos digitales (imágenes, html, PDF, PPTs, vídeos, etc.) podrá introducir contenidos publicitarios en el interior de estos archivos, aunque casi siempre de forma no intrusiva.&lt;/li&gt;
&lt;li&gt;los mails enviados y recibidos a través del servicio &lt;em&gt;Adzure Mail Connector®&lt;/em&gt;, el motor que hay por detrás de Hotmail, también llevarán un mensaje publicitario contextualizado a la temática del mensaje.&lt;/li&gt;
&lt;/ul&gt;
El resto de servicios en la nube (como el almacenamiento en tablas, SQL Server, queues, buses, etc., &lt;em&gt;de momento&lt;/em&gt; están libres de publicidad y pueden ser utilizados libremente y sin restricciones.&lt;br /&gt;
&lt;br /&gt;
Los anuncios se seleccionan de forma automática teniendo en cuenta la temática de la aplicación, el contexto en el que se insertan, el perfil del usuario conectado, y varios factores más. Sin embargo, en lugar de ser gestionados por la plataforma &lt;a href="http://advertising.microsoft.com/espana/inicio"&gt;Microsoft Advertising&lt;/a&gt;, han preferido llegar a &lt;a href="http://www.google.com/blog/why-we-join-microsoft"&gt;un acuerdo con Google&lt;/a&gt; e integrar la&amp;nbsp;&lt;strong&gt;inteligencia de&amp;nbsp;marketing de &lt;/strong&gt;&lt;a href="http://www.blogger.com/www.adsense.com"&gt;&lt;strong&gt;Adsense&lt;/strong&gt;&lt;/a&gt;, bastante depurada, certera y que &lt;a href="http://www.variablenotfound.com/2011/02/no-son-una-leyenda-urbana.html"&gt;tantas alegrías&lt;/a&gt; nos da a sus usuarios. &lt;br /&gt;
&lt;br /&gt;
Pero, ¿y qué ocurre con los ingresos generados por publicidad en las aplicaciones desplegadas en Adzure? Pues una nueva sorpresa: Microsoft los compartirá con los desarrolladores o propietarios del sitio en una proporción del 40% al 60% dependiendo del tráfico. Es decir, no sólo no nos costará utilizar la infraestructura de Adzure, sino que además &lt;strong&gt;podemos ganar dinero&lt;/strong&gt; con ello :-)&lt;br /&gt;
&lt;br /&gt;
Pues no sé qué os parecerá a ustedes, pero yo veo la &lt;strong&gt;idea interesantísima&lt;/strong&gt;. Adzure permite el uso de todos los servicios de la nube de forma gratuita, lo que abre un campo enorme a pequeñas empresas y startups que necesitan disponer de la &lt;strong&gt;gran capacidad de la nube, pero sin incurrir en coste alguno&lt;/strong&gt;, simplemente a cambio de permitir la inserción automática de estos anuncios publicitarios en sus servicios, lo cual en algunos escenarios no tiene por qué ser un problema grave; de hecho, Gmail lo hace y no nos quejamos demasiado ;-) &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.sevillacb.com/"&gt;&lt;img align="right" alt="Sitio web alojado en Adzure con publicidad. Pulsar para verlo &amp;quot;en vivo&amp;quot;." border="0" height="241" src="http://lh3.ggpht.com/-HPMhQeq3dsg/TuNcXe_mIUI/AAAAAAAABsg/5WqMuPLkDsQ/image%25255B24%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 10px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Sitio web alojado en Adzure con publicidad. Pulsar para verlo &amp;quot;en vivo&amp;quot;." width="265" /&gt;&lt;/a&gt;Además, el hecho de que &lt;strong&gt;aspectos infraestructurales&lt;/strong&gt; como los servidores, anchos de banda, seguridad, etc., &lt;strong&gt;pasen de ser un coste a una fuente de ingresos&lt;/strong&gt; me parece una vuelta de tuerca absolutamente necesaria.&lt;br /&gt;
&lt;br /&gt;
De hecho, ya he comenzado a migrar todos mis desarrollos a Adzure,&amp;nbsp;y el resultado está bastante bien (podéis ver una captura en el lateral); sin tocar una línea de código, sólo desplegarlo en la nube, la publicidad insertada se integra perfectamente en los diseños e incluso diría que lo mejoran, y por no hablar de que en unos días ya he conseguido algunos centimillos que nunca vienen mal.&lt;br /&gt;
&lt;br /&gt;
Por cierto, actualmente estos servicios están en fase de beta privada y sólo se puede acceder por invitación, pero tengo &lt;strong&gt;treinta invitaciones para repartir entre los lectores del blog&lt;/strong&gt; que estén &lt;strong&gt;realmente interesados&lt;/strong&gt; en probarlo. Simplemente poneos en contacto conmigo por la vía que os sea más cómoda (por ejemplo &lt;a href="http://www.variablenotfound.com/p/formulario-de-contacto.html"&gt;ésta&lt;/a&gt;) y os iré enviando la URL y password personal de acceso en riguroso orden de llegada.&lt;br /&gt;
&lt;br /&gt;
Y si preferís esperar, el servicio se abrirá al público en general el próximo uno de abril.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: yellow; border: 1px solid black; color: black; padding: 3px;"&gt;
&lt;strong&gt;[Actualizado 29/12]&lt;/strong&gt;&lt;br /&gt;
&lt;em&gt;Nota para despistados:&lt;/em&gt; obviamente la noticia no es real, se trata simplemente de una broma del Día de los Inocentes. Por tanto, lamento comunicaros a los (muchos) que estáis esperando una invitación que de momento no va a poder ser ;-P&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-294681660705501230?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/64SLgC0-8de9jEhsic7fNEoG2Pk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/64SLgC0-8de9jEhsic7fNEoG2Pk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/64SLgC0-8de9jEhsic7fNEoG2Pk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/64SLgC0-8de9jEhsic7fNEoG2Pk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=8EbSMxQN73c:FYbap7twjFc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=8EbSMxQN73c:FYbap7twjFc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=8EbSMxQN73c:FYbap7twjFc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=8EbSMxQN73c:FYbap7twjFc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/8EbSMxQN73c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/294681660705501230/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=294681660705501230" title="7 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/294681660705501230?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/294681660705501230?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/8EbSMxQN73c/adzure-la-nube-gratuita-soportada-por.html" title="Adzure, la nube gratuita soportada por publicidad" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-NlqiGNTEfOU/TuNcVXHUidI/AAAAAAAABsQ/dEoPlwFhlAU/s72-c/image7%25255B1%25255D.png?imgmax=800" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/adzure-la-nube-gratuita-soportada-por.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4ESHs4eSp7ImA9WhRXGUo.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-1337051541985477914</id><published>2011-12-27T10:08:00.000+01:00</published><updated>2011-12-27T10:08:29.531+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-27T10:08:29.531+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="data" /><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="azure" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>Enlaces interesantes 65</title><content type="html">&lt;a href="http://lh5.ggpht.com/-n2quf1DUdXA/TvcLF8baMVI/AAAAAAAABtE/Zk1NM13lenw/s1600-h/image73.png"&gt;&lt;img align="right" alt="Enlaces interesantes: .NET, ASP.NET, Azure, HTML, CSS, javascript, Visual Studio" border="0" height="129" src="http://lh5.ggpht.com/-Ma3OZcUBcIk/TvcLGqGv-LI/AAAAAAAABtM/k-7Ov_mpt54/image7_thumb.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes: .NET, ASP.NET, Azure, HTML, CSS, javascript, Visual Studio" width="172" /&gt;&lt;/a&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 18 al 23 de diciembre de 2011. Espero que os resulten interesantes. :-) &lt;br /&gt;
&lt;h4&gt;
.Net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://tirania.org/blog/archive/2011/Dec-21.html"&gt;&lt;strong&gt;Mono in 2011&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Miguel de Icaza &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Asp.net&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.liamcavanagh.com/2011/12/how-to-combine-a-worker-role-with-a-mvc4-web-role-into-a-single-instance/"&gt;&lt;strong&gt;How to combine a Worker Role with a MVC4 Web Role into a single instance&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Liam Cavanagh &lt;/li&gt;
&lt;li&gt;&lt;a href="http://stephenwalther.com/blog/archive/2011/12/22/asp-net-mvc-selenium-iisexpress.aspx"&gt;&lt;strong&gt;ASP.NET MVC + Selenium + IISExpress&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Stephen Walther &lt;/li&gt;
&lt;li&gt;&lt;a href="http://dailydotnettips.com/2011/12/20/model-binding-with-dropdown-list-in-asp-net-4-5/"&gt;&lt;strong&gt;Model Binding with Dropdown List in ASP.NET 4.5&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Abhijit Jana &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blog.stevensanderson.com/2011/12/21/knockout-2-0-0-released/"&gt;Knockout 2.0.0 released&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Steve Sanderson &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.troyhunt.com/2011/12/free-ebook-owasp-top-10-for-net.html"&gt;&lt;strong&gt;Free eBook: OWASP Top 10 for .NET developers&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Troy Hunt &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/imranbaloch/archive/2011/12/19/solving-duplicate-content-issue-in-asp-net.aspx"&gt;Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Imran Baloch's &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/sreejukg/archive/2011/12/20/new-request-validation-features-in-asp-net-4-5.aspx"&gt;New Request validation features in ASP.Net 4.5&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;K. G. Sreeju Nair &lt;/li&gt;
&lt;li&gt;&lt;a href="http://encosia.com/using-cors-to-access-asp-net-services-across-domains/"&gt;&lt;strong&gt;Using CORS to access ASP.NET services across domains&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Dave Ward &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/etomas/archive/2011/12/19/httprequestbase-vs-httprequest.aspx"&gt;HttpRequestBase vs HttpRequest&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Eduard Tomás &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2011/Dec/15/Debugging-ApplicationStart-and-Module-Initialization-with-IIS-and-Visual-Studio" title="Debugging Application_Start and Module Initialization with IIS and Visual Studio"&gt;&lt;strong&gt;Debugging Application_Start and Module Initialization with IIS and Visual Studio&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Rick Strahl &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=778"&gt;Rotate an ASP.NET Image Control using HTML 5 Canvas&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Suprotim Agarwal &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/lontivero/archive/2011/12/17/retoques-a-mvc-y-razor-para-proyectos-grandes-una-recomendaci-243-n.aspx"&gt;&lt;strong&gt;Retoques a MVC y Razor para proyectos grandes–Una recomendación&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Lucas Ontivero &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://visualstudiomagazine.com/Articles/2011/12/01/High-Performance-ASPNET-Caching.aspx?Page=1"&gt;High-Performance ASP.NET Caching&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Peter Vogel &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mattwrock.com/post/2011/12/15/Microsoft-blogging-platform-gains-33-performance-boost-after-adopting-RequestReduce.aspx" title="Microsoft blogging platform gains 33% performance boost after adopting RequestReduce"&gt;&lt;strong&gt;Microsoft blogging platform gains 33% performance boost after adopting RequestReduce&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Matt Wrocks &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Azure / Cloud&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.estoyenlanube.com/azure-monitor-for-windows-phone-7-is-out/"&gt;Azure Monitor for Windows Phone 7 is out!&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ibon Landa &lt;/li&gt;
&lt;li&gt;&lt;a href="http://es.scribd.com/doc/76037307/Subete-a-la-nube-de-Microsoft-Parte-4-Diseno-y-Herramientas"&gt;&lt;strong&gt;Libro gratuito sobre Windows Azure (Parte IV): Diseño y herramientas&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;CampusMVP &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.estoyenlanube.com/sql-azure-q4-2011-service-release/"&gt;SQL Azure Q4 2011 Service Release&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ibon Landa &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Data access&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2011/mongodb-best-practices/"&gt;&lt;strong&gt;MongoDB Best Practices&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Inés Sombra &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jyeray/archive/2011/12/21/windows-phone-7-5-inserciones-masivas-en-sql-server-ce-vs-sql-server-vs-mongodb-y-ii.aspx"&gt;Inserciones masivas en SQL Server CE vs SQL Server vs MongoDb (y II)&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Josué Yeray &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2011/12/19/raven-db-vi-la-hora-de-las-consultas.aspx"&gt;Raven DB VI, La hora de las consultas…&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Unai Zorrilla &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Html/Css/Javascript&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://ejohn.org/blog/javascript-as-a-first-language/"&gt;&lt;strong&gt;JavaScript as a First Language&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;John Resig &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://html5doctor.com/the-output-element/"&gt;The output element in HTML5&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Richard Clark &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.excssive.com/"&gt;&lt;strong&gt;Excssive, herramienta online para comprimir archivos CSS&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Zach Will (Vía desarrolloweb.com) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.red-team-design.com/meet-the-css4-selectors"&gt;Meet the CSS4 selectors&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Catalin Rosu       &lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-calling-functions-and-the-lsquo-this-rsquo-variable/"&gt;&lt;strong&gt;JavaScript for C# developers: calling functions and the ‘this’ variable&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Julian M. Bucknall &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.developerdrive.com/2011/08/top-10-must-follow-javascript-best-practices-2/"&gt;Top 10 “Must Follow” JavaScript Best Practices&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Salman Siddiqui &lt;/li&gt;
&lt;li&gt;&lt;a href="http://jscompress.com/"&gt;&lt;strong&gt;Online Javascript Compression Tool&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;BrightBit &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://dannorth.net/2011/12/19/the-rise-and-rise-of-javascript/"&gt;The rise and rise of JavaScript&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Dan North &lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2011/12/19/using-the-javascript-prototype-property-to-structure-and-extend-code.aspx"&gt;&lt;strong&gt;Using the JavaScript Prototype Property to Structure and Extend Code&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Dan Wahlin's &lt;/li&gt;
&lt;li&gt;&lt;a href="http://css-tricks.com/multiple-attribute-values/"&gt;&lt;strong&gt;Multiple Attribute Values&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Chris Coyier &lt;/li&gt;
&lt;li&gt;&lt;a href="http://coding.smashingmagazine.com/2010/02/22/the-seven-deadly-sins-of-javascript-implementation/" title="The Seven Deadly Sins Of JavaScript Implementation"&gt;&lt;strong&gt;The Seven Deadly Sins Of JavaScript Implementation&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Christian Heilmann (vía @alegrebandolero) &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Visual Studio/Complementos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/2011/12/22/c-resharper-awesome-tip-5-replace-constructor-with-factory-method/"&gt;&lt;strong&gt;C# + ReSharper = Awesome: Tip #5 – Replace Constructor with Factory Method&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alvin Ashcraft &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.jetbrains.com/dotnet/2011/12/christmas-is-here-resharper-61-dotcover-12-and-dottrace-452-released/"&gt;&lt;strong&gt;ReSharper 6.1, dotCover 1.2 and dotTrace 4.5.2 Performance Released&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Hadi Hariri &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/2011/12/20/c-resharper-awesome-tip-4-convert-abstract-class-to-interface/"&gt;&lt;strong&gt;C# + ReSharper = Awesome: Tip #4 – Convert Abstract Class to Interface&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alvin Ashcraft &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/2011/12/16/c-resharper-awesome-tip-3-convert-into-linq-expression/"&gt;&lt;strong&gt;C# + ReSharper = Awesome: Tip #3 – Convert Into LINQ Expression&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alvin Ashcraft&lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-1337051541985477914?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gKR7k4ENX3T5UcPRshZrEWtViGY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gKR7k4ENX3T5UcPRshZrEWtViGY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gKR7k4ENX3T5UcPRshZrEWtViGY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gKR7k4ENX3T5UcPRshZrEWtViGY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=9ZXWnWM-5ck:ydzXNtEm44Y:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=9ZXWnWM-5ck:ydzXNtEm44Y:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=9ZXWnWM-5ck:ydzXNtEm44Y:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=9ZXWnWM-5ck:ydzXNtEm44Y:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/9ZXWnWM-5ck" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/1337051541985477914/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=1337051541985477914" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/1337051541985477914?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/1337051541985477914?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/9ZXWnWM-5ck/enlaces-interesantes-65.html" title="Enlaces interesantes 65" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-Ma3OZcUBcIk/TvcLGqGv-LI/AAAAAAAABtM/k-7Ov_mpt54/s72-c/image7_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/enlaces-interesantes-65.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8NSHo7fSp7ImA9WhRXFkk.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-8091922337078068513</id><published>2011-12-23T12:52:00.001+01:00</published><updated>2011-12-23T14:44:59.405+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-23T14:44:59.405+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="navidad" /><category scheme="http://www.blogger.com/atom/ns#" term="blogging" /><title>¡Felices fiestas &amp; 2012!</title><content type="html">&lt;img align="right" alt="Feliz Navidad" border="0" height="157" src="http://lh5.ggpht.com/_O9D62hXq-ng/TRO4Ff7YI9I/AAAAAAAABZI/tO4lKrb_wmY/image%5B24%5D.png?imgmax=800" style="margin: 0px 0px 10px 10px;" title="Feliz Navidad" width="208" /&gt;Desearos a todos unas muy felices fiestas en las que podáis disfrutar de la compañía de todos aquellos que os importan. &lt;br /&gt;
&lt;br /&gt;
Y ya de paso, desearos también que el próximo año 2012 venga cargado de alegrías, prosperidad y nada más que cosas buenas. Al menos a ver si es para todos un pelín mejor de lo que ha sido el año que ahora cerramos ;-)&lt;br /&gt;
&lt;br /&gt;
Nos seguimos viendo por aquí.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-8091922337078068513?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nmME6k4ANZWfw5KzKEa4-2mB93A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nmME6k4ANZWfw5KzKEa4-2mB93A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nmME6k4ANZWfw5KzKEa4-2mB93A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nmME6k4ANZWfw5KzKEa4-2mB93A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=iIE7cVoerX8:Vn_d3ErvCwU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=iIE7cVoerX8:Vn_d3ErvCwU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=iIE7cVoerX8:Vn_d3ErvCwU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=iIE7cVoerX8:Vn_d3ErvCwU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/iIE7cVoerX8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/8091922337078068513/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=8091922337078068513" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/8091922337078068513?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/8091922337078068513?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/iIE7cVoerX8/felices-fiestas-2012.html" title="¡Felices fiestas &amp; 2012!" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_O9D62hXq-ng/TRO4Ff7YI9I/AAAAAAAABZI/tO4lKrb_wmY/s72-c/image%5B24%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/felices-fiestas-2012.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UASXo5fSp7ImA9WhRXE0s.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-971269652498920088</id><published>2011-12-20T09:20:00.000+01:00</published><updated>2011-12-20T09:20:48.425+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-20T09:20:48.425+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desarrollo" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><title>IMetadataAware, atributos de metadatos personalizados</title><content type="html">&lt;img align="right" alt="ASP.NET MVC" border="0" height="77" src="http://lh4.ggpht.com/-2HspJJFbBX8/TuJo7b4smRI/AAAAAAAABrw/yV3hOs4QggA/ASPNETMVC2.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ASP.NET MVC" width="142" /&gt;Hace pocas semanas profundizamos en los &lt;a href="http://www.variablenotfound.com/2011/11/mama-de-donde-vienen-los-metadatos.html"&gt;mecanismos de obtención de metadatos del modelo en ASP.NET MVC&lt;/a&gt; y vimos cómo extender el framework para dotarlo de vías alternativas desde las que obtener esta información usando un proveedor personalizado.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, no es este el único mecanismo de extensión del framework a este respecto: también podemos crear fácilmente nuevos atributos que aporten información extra de metadatos a las clases y propiedades del Modelo. Y esta es la razón de ser del interfaz &lt;code&gt;IMetadataAware&lt;/code&gt;.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h3&gt; El interfaz IMetadataAware&lt;/h3&gt;Definido en &lt;code&gt;System.Web.Mvc&lt;/code&gt; e introducido con la tercera versión del framework, este interfaz permite crear atributos que encajen muy suavemente en el sistema de generación y obtención de metadatos de ASP.NET MVC, evitando en muchos escenarios la necesidad de escribir proveedores personalizados.&lt;br /&gt;
Como podemos ver a continuación, su definición es de lo más simple:&lt;br /&gt;
&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;interface&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IMetadataAware&lt;/span&gt;
{
&lt;span style="color: blue;"&gt;&lt;span style="color: black;"&gt;    &lt;/span&gt;void&lt;/span&gt; OnMetadataCreated(ModelMetadata metadata);
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;img align="right" alt="ModelMetadata (parcial)" border="0" height="220" src="http://lh5.ggpht.com/-1UZFmP-EYPA/TuJo8CZa4II/AAAAAAAABr4/ZQ3wzceTRZI/image%25255B16%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ModelMetadata (parcial)" width="177" /&gt;¿Y cómo se utiliza esto internamente? Pues la respuesta la podemos encontrar buceando un poco en el código fuente del framework.&lt;br /&gt;
&lt;br /&gt;
Durante el proceso de obtención de metadatos, el proveedor &lt;code&gt;DataAnnotationsModelMetadataProvider &lt;/code&gt;(en conjunción con su tipo base &lt;code&gt;AssociatedMetadataProvider&lt;/code&gt;), obtiene los metadatos “estándar” y los introduce en un objeto de tipo &lt;code&gt;&lt;a href="http://msdn.microsoft.com/es-es/library/system.web.mvc.modelmetadata.aspx" title="ModelMetadata en MSDN"&gt;ModelMetadata&lt;/a&gt;&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Una vez tenemos ya esta información, obtenida según el comportamiento por defecto desde los atributos conocidos que decoran las propiedades del Modelo, se ejecuta el método estático &lt;code&gt;ApplyMetadataAwareAttributes(),&amp;nbsp;&lt;/code&gt;que tiene la siguiente pinta:&lt;br /&gt;
&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; ApplyMetadataAwareAttributes(
                          &lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;Attribute&lt;/span&gt;&amp;gt; attributes, 
                          &lt;span style="color: #2b91af;"&gt;ModelMetadata&lt;/span&gt; result)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;IMetadataAware&lt;/span&gt; awareAttribute &lt;span style="color: blue;"&gt;in&lt;/span&gt; attributes.OfType&amp;lt;&lt;span style="color: #2b91af;"&gt;IMetadataAware&lt;/span&gt;&amp;gt;())
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; awareAttribute.OnMetadataCreated(result);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
} &lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Como se puede deducir a la vista del código, el método es invocado suministrándole, por una parte, todos los atributos localizados en la clase del Modelo, y por otra, el objeto &lt;code&gt;ModelMetadata&lt;/code&gt; que contiene la información de metadatos obtenidos hasta el momento.&lt;br /&gt;
&lt;br /&gt;
Ya en su interior, lo único que se hace es obtener todos aquellos atributos que implementen el interfaz &lt;code&gt;IMetadataAware&lt;/code&gt; y llamar a su único método &lt;code&gt;OnMetadataCreated()&lt;/code&gt; con objeto de que actualicen los metadatos con la información que necesiten.&lt;br /&gt;
&lt;br /&gt;
Por tanto, en la práctica, si queremos crear un atributo que introduzca información adicional de metadatos, o simplemente modifique los existentes, debemos:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;crear un atributo como siempre, heredando de &lt;code&gt;Attribute&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;hacer que la clase implemente el interfaz &lt;code&gt;IMetadataAware&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;implementar en el método &lt;code&gt;OnMetadataCreated()&lt;/code&gt; para introducir la metainformación que nos interese en el objeto &lt;code&gt;ModelMetadata&lt;/code&gt; que recibimos como parámetro .&lt;/li&gt;
&lt;/ul&gt;Por ejemplo:&lt;br /&gt;
&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MyMetadataAttribute&lt;/span&gt;: &lt;span style="color: #2b91af;"&gt;Attribute&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;IMetadataAware&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnMetadataCreated(&lt;span style="color: #2b91af;"&gt;ModelMetadata&lt;/span&gt; metadata)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Set properties...&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metadata.DisplayName = &lt;span style="color: #a31515;"&gt;"My text"&lt;/span&gt;;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// ... or add new properties to AdditionalValues&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metadata.AdditionalValues[&lt;span style="color: #a31515;"&gt;"MyKey"&lt;/span&gt;] =&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #a31515; font-family: Consolas; font-size: 13px;"&gt;"My value"&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Consolas; font-size: 13px;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Observad que en el cuerpo del método tenemos acceso a todas las propiedades de metadatos, así como a su diccionario&amp;nbsp;&lt;code&gt;AdditionalValues&lt;/code&gt;, donde podemos introducir cualquier tipo de información que nos interese poner a disposición de la Vista.&lt;br /&gt;
&lt;h3&gt; ¿Un ejemplo rápido?&lt;/h3&gt;Vamos a desarrollar un atributo de metadatos personalizado al que llamaremos &lt;code&gt;Important&lt;/code&gt;, y que hará lo siguiente:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;en primer lugar, añadirá al &lt;code&gt;DisplayName&lt;/code&gt; de la propiedad (el texto que aparece en su correspondiente etiqueta) el sufijo “important!”.&lt;/li&gt;
&lt;li&gt;añadirá a la colección &lt;code&gt;AdditionalValues&lt;/code&gt; un valor que permita a la vista destacar el editor de la propiedad visualmente.&lt;/li&gt;
&lt;/ul&gt;(Ojo, que hay otras formas para conseguir este mismo resultado, pero el post trata sobre &lt;code&gt;IMetadataAware&lt;/code&gt;, así que tendremos que quedarnos con esta ;-))&lt;br /&gt;
&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ImportantAttribute&lt;/span&gt;: &lt;span style="color: #2b91af;"&gt;Attribute&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;IMetadataAware&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnMetadataCreated(&lt;span style="color: #2b91af;"&gt;ModelMetadata&lt;/span&gt; metadata)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metadata.DisplayName = metadata.GetDisplayName() + &lt;span style="color: #a31515;"&gt;" (important!)"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metadata.AdditionalValues[&lt;span style="color: #a31515;"&gt;"Important"&lt;/span&gt;] = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Eso es todo lo que necesitamos en nuestro atributo. Hecho esto, ya podemos utilizarlo en una clase del Modelo como se muestra a continuación:&lt;br /&gt;
&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Important&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Email { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Important&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Phone { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; Fax { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;El simple hecho de decorar las propiedades &lt;code&gt;Name&lt;/code&gt; y &lt;code&gt;Phone&lt;/code&gt; con nuestro flamante atributo &lt;code&gt;[Important]&lt;/code&gt; hará que sus etiquetas descriptivas aparezcan ya con el sufijo “important!”, puesto que estamos modificando directamente su &lt;code&gt;DisplayName&lt;/code&gt;. Si queremos además destacar los editores necesitaremos inyectar un poco de lógica en la vista, cosa que podemos hacer de forma relativamente sencilla implementando un helper o modificando las plantillas de edición por defecto para los tipos utilizados (en este caso, strings).&lt;br /&gt;
&lt;br /&gt;
Una implementación rápida de un helper que genere código script para destacar las propiedades importantes podría ser la siguiente. Si os fijáis, lo único que hace es obtener aquellas propiedades en cuyos metadatos exista la entrada de &lt;code&gt;AdditionalValues&lt;/code&gt; establecida en el atributo &lt;code&gt;[Important]&lt;/code&gt;, y establecer en sus editores la clase CSS “important” para darles un poco de color:&lt;br /&gt;
&lt;pre style="background-color: transparent; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlExtensions&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt; HighlightImportant(&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlHelper&lt;/span&gt; html)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; template = html.ViewData.TemplateInfo;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; importantProps = &lt;span style="color: blue;"&gt;from&lt;/span&gt; property &lt;span style="color: blue;"&gt;in&lt;/span&gt; html.ViewData.ModelMetadata.Properties
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;where&lt;/span&gt; property.AdditionalValues.Any(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a =&amp;gt; a.Key == &lt;span style="color: #a31515;"&gt;"Important"&lt;/span&gt; &amp;amp;&amp;amp; (&lt;span style="color: blue;"&gt;bool&lt;/span&gt;)a.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;select&lt;/span&gt; template.GetFullHtmlFieldId(property.PropertyName);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (importantProps.Any())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; commaIds = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #a31515;"&gt;",#"&lt;/span&gt;, importantProps);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; script = &lt;span style="color: #a31515;"&gt;"&amp;lt;script type='text/javascript'&amp;gt;"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"$(function() { $('#"&lt;/span&gt; + commaIds + &lt;span style="color: #a31515;"&gt;"').addClass('important'); });"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"&amp;lt;/script&amp;gt;"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt;.Create(script);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;null&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;img align="right" alt="El atributo Important en acción" border="0" height="240" src="http://lh6.ggpht.com/-_SEWGTGoCO8/TuJo83yIM3I/AAAAAAAABsA/qGIZYcjgDEQ/image%25255B20%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="El atributo Important en acción" width="185" /&gt;Obviamente, tendríamos que incluir una llamada al helper &lt;code&gt;Html.HighlightImportant()&lt;/code&gt; en las vistas o, si queremos mayor comodidad, en el Layout del sitio web.&lt;br /&gt;
&lt;br /&gt;
En la captura de pantalla de la derecha podéis ver el resultado de este ejemplo en funcionamiento. Y si queréis probarlo y juguetear un rato con él, podéis &lt;a href="https://skydrive.live.com/redir.aspx?cid=c3a43a99b617d787&amp;amp;resid=C3A43A99B617D787!275&amp;amp;parid=C3A43A99B617D787!274&amp;amp;authkey=!ADC1n6uN9cwn_wM"&gt;descargar el proyecto para Visual Studio y ASP.NET MVC 3 desde mi Skydrive&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-971269652498920088?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ldUs3J-U0_DltMAKsQX2njbqRt8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ldUs3J-U0_DltMAKsQX2njbqRt8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ldUs3J-U0_DltMAKsQX2njbqRt8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ldUs3J-U0_DltMAKsQX2njbqRt8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=7SSzh3I8Ph8:5-TEItiMcg8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=7SSzh3I8Ph8:5-TEItiMcg8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=7SSzh3I8Ph8:5-TEItiMcg8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=7SSzh3I8Ph8:5-TEItiMcg8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/7SSzh3I8Ph8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/971269652498920088/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=971269652498920088" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/971269652498920088?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/971269652498920088?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/7SSzh3I8Ph8/imetadataaware-atributos-de-metadatos.html" title="IMetadataAware, atributos de metadatos personalizados" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-2HspJJFbBX8/TuJo7b4smRI/AAAAAAAABrw/yV3hOs4QggA/s72-c/ASPNETMVC2.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/imetadataaware-atributos-de-metadatos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYEQH05fyp7ImA9WhRXEkU.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-2446339596292869922</id><published>2011-12-19T09:25:00.000+01:00</published><updated>2011-12-19T09:25:01.327+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-19T09:25:01.327+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visualstudio" /><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="azure" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>Enlaces interesantes 64</title><content type="html">&lt;img align="right" alt="Enlaces interesantes: .NET, ASP.NET, Azure, HTML, CSS, Visual Studio" border="0" height="129" src="http://lh6.ggpht.com/-uavC66lr6W8/TuySkExddoI/AAAAAAAABsw/shB7arJlTbg/image%25255B7%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Enlaces interesantes: .NET, ASP.NET, Azure, HTML, CSS, Visual Studio" width="172" /&gt;Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 12 al 17 de diciembre de 2011. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;br /&gt;
Aprovecho además para pediros opinión sobre un nuevo formato de presentación de los enlaces, usando categorizaciones. De esta forma podréis acceder directamente a aquellos cuya temática os interese, en lugar de tener que leerlos todos para ver si hay alguno que al que valga la pena echar el vistazo. ¿Qué os parece? ¿Mejor así?&lt;br /&gt;
&lt;h4&gt; .Net&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.blackwasp.co.uk/EnumFormat.aspx"&gt;&lt;strong&gt;Formatting Enumeration Constants&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
BlackWasp &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/kirillosenkov/archive/2011/12/13/install-package-roslyn.aspx"&gt;Install-Package Roslyn&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Kirill Osenkov &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://visualstudiomagazine.com/blogs/tool-tracker/2011/12/return-multiple-values-from-methods-with-tuples.aspx"&gt;Return Multiple Values from Methods with Tuples&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Peter Vogel &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blackrabbitcoder.net/archive/2011/12/08/c-fundamentals-returning-zero-or-one-item-as-ienumerablelttgt.aspx" title="Title of this entry"&gt;&lt;strong&gt;C# Fundamentals: Returning Zero or One Item As IEnumerable&amp;lt;T&amp;gt;&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
James Michael Hare &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lontivero/archive/2011/12/10/net-reflector-y-ilspy-191-podr-237-an-inferir-mejor-el-c-243-digo-a-partir-del-il.aspx"&gt;.Net Reflector y ILSpy, ¿podrían inferir mejor el código a partir del IL?&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Lucas Ontivero &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Asp.net&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://geeks.ms/blogs/lruiz/archive/2011/12/15/video-asp-net-vnext-filtrado-de-datos-value-provider-attributes.aspx"&gt;&lt;strong&gt;[Video] ASP.NET vNext - Filtrado de datos - Value Provider Attributes&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Luis Ruiz &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.iwantmymvc.com/mvc-3-signalr-knockout-real-time-notifications"&gt;&lt;strong&gt;How to use SignalR and Knockout in an ASP.NET MVC 3 web application to handle real-time UX updates&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Justin Schwartzenberger &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://deanhume.com/Home/BlogPost/mvc-and-html5-web-workers/66"&gt;MVC and HTML5 Web Workers&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Dean hume &lt;/li&gt;
&lt;li&gt;&lt;a href="http://buildstarted.com/2011/12/07/introducing-signalr-eventstream/"&gt;&lt;strong&gt;Introducing SignalR.EventStream&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Ben Dornis &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.webpirates.nl/robin-van-der-knaap/33-updated-jqgrid-html-helper-for-aspnet-mvc"&gt;Update jqGrid Html helper for ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Robin van der Knaap &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeproject.com/KB/aspnet/ASPNET-MVC-Security.aspx"&gt;Implement secure ASP.NET MVC applications&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Jovan Popovic &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.webperformance.com/load-testing/blog/2011/11/what-is-the-fastest-webserver/"&gt;Which is the Fastest Webserver? Apache, IIS, Nginx, LightHttpd or G-Wan?&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
WebPerformance (vía @campusmvp) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.troyhunt.com/2011/12/owasp-top-10-for-net-developers-part-10.html"&gt;&lt;strong&gt;OWASP Top 10 for .NET developers part 10: Unvalidated Redirects and Forwards&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Troy Hunt &lt;/li&gt;
&lt;li&gt;&lt;a href="http://freshbrewedcode.com/davidneal/2011/12/12/espresso-tip-ihttphandler-and-isreusable/"&gt;&lt;strong&gt;Espresso Tip: IHttpHandler and IsReusable&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
David Neal &lt;/li&gt;
&lt;li&gt;&lt;a href="http://panicoenlaxbox.blogspot.com/2011/12/introduccion-less.html"&gt;&lt;strong&gt;Introducción a less&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Sergio León &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://puredotnetcoder.blogspot.com/2011/12/automatically-trim-html-controls-in.html"&gt;Automatically trim html controls in a asp.net mvc project&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Richard Wilde &lt;/li&gt;
&lt;li&gt;&lt;a href="http://lunarfrog.com/blog/2011/12/09/aspnetsite-as-desktop-app/"&gt;&lt;strong&gt;On deploying ASP.NET MVC site as a desktop application&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Andrei Marukovich &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jasoft.org/Blog/post/Todo-sobre-AutoEventWireUp-en-paginas-ASPNET-Web-Forms.aspx"&gt;&lt;strong&gt;Todo sobre AutoEventWireUp en páginas ASP.NET Web Forms&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;a href="http://haacked.com/archive/2011/12/10/using-qunit-with-razor-layouts.aspx"&gt;&lt;strong&gt;Using QUnit with Razor Layouts&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Phil Haack &lt;/li&gt;
&lt;li&gt;&lt;a href="http://kazimanzurrashid.com/posts/asp-dot-net-mvc-viewmodel-usage-and-pick-your-best-pattern"&gt;&lt;strong&gt;ASP.NET MVC ViewModel usage and pick your best pattern&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Kazi Manzur Rashid &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://mvcrouteunittester.codeplex.com/"&gt;MVC Route/URL Generation Unit Tester&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Codeplex &lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/jalpeshpvadgama/archive/2011/12/11/easy-url-rewriting-in-asp-net-4-0-web-forms.aspx"&gt;&lt;strong&gt;Easy URL rewriting in ASP.NET 4.0 web forms&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Jalpesh Vadgama &lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/dotnetstories/archive/2011/12/08/looking-into-web-performance-in-asp-net-applications.aspx"&gt;&lt;strong&gt;Looking into Web performance in ASP.Net applications&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Nikolaos Kantzelis &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lruiz/archive/2011/12/09/video-asp-net-vnext-selecci-243-n-de-datos-selectmethod.aspx"&gt;[Vídeo] ASP.NET vNext - Selección de datos (SelectMethod)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Luis Ruiz &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blog.maartenballiauw.be/post/2011/12/06/Using-SignalR-to-broadcast-a-slide-deck.aspx"&gt;Using SignalR to broadcast a slide deck&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Marteen Balliauw &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Azure / Cloud&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.returngis.net/2011/12/utilizar-windows-azure-appfabric-caching-como-session-provider/"&gt;&lt;strong&gt;Utilizar Windows Azure AppFabric Caching como session provider&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Gisela Torres &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.zdnet.com/blog/microsoft/vmware-cloud-foundry-cloud-platform-now-supports-net/11425"&gt;&lt;strong&gt;VMware Cloud Foundry cloud platform now supports .Net&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Mary-Joe Foley &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/windowsazure/archive/2011/12/12/now-available-sql-azure-q4-2011-service-release.aspx"&gt;Now Available: SQL Azure Q4 2011 Service Release&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Azure Team (vía @ibonilm) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://oakleafblog.blogspot.com/2011/12/sql-azure-team-unveils-new-server.html"&gt;&lt;strong&gt;The SQL Azure Team Unveils a New Server Management UI&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Roger Jennings &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg433135.aspx"&gt;Differences Between the Storage Emulator and Windows Azure Storage Services&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
MSDN &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Conceptos&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.cs.uiuc.edu/~jeffe/teaching/algorithms/"&gt;Algorithms Course Materials&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Jeff Erickson       &lt;ul&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://home.comcast.net/~bretm/hash/"&gt;&lt;strong&gt;Hash Functions&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Bret Mulvey &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Data access&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2011/12/12/ravendb-iv-la-identidad-de-los-documentos.aspx"&gt;RavenDB (IV) La identidad de los documentos&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Unai Zorrilla &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.luisrocha.net/2011/12/data-access-performance-comparison-in.html" title="Data Access Performance Comparison in .NET"&gt;&lt;strong&gt;Data Access Performance Comparison in .NET&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Luis Rocha &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Html/Css/Javascript&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.jquery4u.com/forms/10-jquery-form-plugins/"&gt;10 Best jQuery Form Plugins&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
jQuery4u &lt;/li&gt;
&lt;li&gt;&lt;a href="http://24ways.org/2011/your-jquery-now-with-less-suck"&gt;&lt;strong&gt;Your jQuery: Now With 67% Less Suck&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Scott Kosman &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/shair/archive/2011/12/11/javascript-add-commas-to-number.aspx"&gt;JavaScript – Add Commas To Number&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Shai Raiten &lt;/li&gt;
&lt;li&gt;&lt;a href="http://calendar.perfplanet.com/2011/frontend-spof-in-beijing/"&gt;&lt;strong&gt;Frontend SPOF&lt;/strong&gt; &lt;/a&gt;      &lt;br /&gt;
Steve Souders &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.awcore.com/js/news/15/the-30-most-effective-jquery-plugins_en"&gt;&lt;strong&gt;The 30 Most Effective jQuery Plugins&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Awcore &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/HTML/HTML5Animations.aspx"&gt;&lt;strong&gt;Animations in HTML5&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Florian Rappl &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2011/Dec/10/HTML-5-Input-Types-How-useful-is-this-really-going-to-be"&gt;&lt;strong&gt;HTML 5 Input Types - How useful is this really going to be?&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Rick Strahl &lt;/li&gt;
&lt;li&gt;&lt;a href="http://bricss.net/post/13884376788/the-css-profilers-are-coming"&gt;&lt;strong&gt;The CSS profilers are coming!&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Lennart Schoors &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2011/Dec/08/A-Key-Code-Checker-for-DOM-Keyboard-Events"&gt;&lt;strong&gt;A Key Code Checker for DOM Keyboard Events&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Rick Strahl &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Visual Studio/Complementos&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2011/12/15/howto-agregar-ficheros-a-un-proyecto-existente.aspx"&gt;[HowTo] Agregar Ficheros a un Proyecto Existente&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Javier Torrecilla &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/2011/12/14/c-resharper-awesome-tip-2-create-field/"&gt;&lt;strong&gt;C# + ReSharper = Awesome: Tip #2 – Create Field&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Alvin Ashcraft &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://docs.nuget.org/docs/release-notes/nuget-1.6"&gt;NuGet 1.6 Release Notes&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Nuget Team &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2011/12/12/how-to-agregar-un-elemento-de-men-250-a-visual-studio.aspx"&gt;&lt;strong&gt;[How To] Agregar un elemento de menú a Visual Studio.&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Javier Torrecilla &lt;/li&gt;
&lt;li&gt;&lt;a href="http://dailydotnettips.com/2011/12/09/go-to-definition-for-javascript-functions-in-visual-studio-2011/"&gt;&lt;strong&gt;Go To Definition for JavaScript Functions in Visual Studio 2011&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Abhijit Jana &lt;/li&gt;
&lt;li&gt;&lt;a href="http://madskristensen.net/post/Introducing-CSSCop-FxCop-for-stylesheets.aspx" title="Introducing CSSCop - FxCop for stylesheets"&gt;&lt;strong&gt;Introducing CSSCop - FxCop for stylesheets&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Mads Kristensen &lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt; Otros&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://jmalarcon.es/post/La-fruta-mas-alta-siempre-sabe-mejor.aspx"&gt;&lt;strong&gt;La fruta más alta siempre sabe mejor&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
José Manuel Alarcón &lt;/li&gt;
&lt;/ul&gt;Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.     &lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-2446339596292869922?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CBsIuc-jVaNFko8r_NL5ewjOW2M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CBsIuc-jVaNFko8r_NL5ewjOW2M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CBsIuc-jVaNFko8r_NL5ewjOW2M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CBsIuc-jVaNFko8r_NL5ewjOW2M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=gVz95v_qYLQ:SF78NS_Kvg4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=gVz95v_qYLQ:SF78NS_Kvg4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=gVz95v_qYLQ:SF78NS_Kvg4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gVz95v_qYLQ:SF78NS_Kvg4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/gVz95v_qYLQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/2446339596292869922/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=2446339596292869922" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/2446339596292869922?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/2446339596292869922?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/gVz95v_qYLQ/enlaces-interesantes-64.html" title="Enlaces interesantes 64" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-uavC66lr6W8/TuySkExddoI/AAAAAAAABsw/shB7arJlTbg/s72-c/image%25255B7%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/enlaces-interesantes-64.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cGQXc6eSp7ImA9WhRXEkU.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-3479158616767085156</id><published>2011-12-19T08:50:00.000+01:00</published><updated>2011-12-19T08:50:20.911+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-19T08:50:20.911+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="auges" /><category scheme="http://www.blogger.com/atom/ns#" term="eventos" /><title>[Auges] Inyección de dependencias en ASP.NET</title><content type="html">&lt;img align="right" alt="Auges" border="0" height="42" src="http://lh4.ggpht.com/-qKrmbmN3Pxc/Tu3nLlCIkYI/AAAAAAAABtA/wzH0hWHjv0k/logoauges%25255B4%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Auges" width="182" /&gt;Mañana, martes 20 de diciembre de 2011, a las 19:00h (GMT+1) en AUGES tendremos el placer de contar con la presencia de Luis Ruiz Pavón, &lt;em&gt;alma mater&lt;/em&gt; del grupo y gran conocido en la comunidad de desarrolladores .NET, para&amp;nbsp;explicarnos &lt;strong&gt;qué es, para qué sirve y cómo se usa la Inyección de Dependencias&lt;/strong&gt;, especialmente enfocado al desarrollo &lt;strong&gt;con ASP.NET&lt;/strong&gt;. &lt;br /&gt;
&lt;blockquote&gt;En este WebCast veremos una introducción a la inyección de dependencias en ASP.NET con ejemplos prácticos:     &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;¿Qué es la inyección de dependencias?&lt;/li&gt;
&lt;li&gt;¿Que nos aporta?&lt;/li&gt;
&lt;li&gt;Patrones y anti-patrones.&lt;/li&gt;
&lt;li&gt;¿Dónde se construye el grafo?&lt;/li&gt;
&lt;li&gt;Tiempo de vida de las dependencias.&lt;/li&gt;
&lt;li&gt;Contenedores de dependencias (IoC Containers)&lt;/li&gt;
&lt;li&gt;¿Cómo se aplica todo esto en ASP.NET?&lt;/li&gt;
&lt;/ul&gt;&lt;u&gt;&lt;strong&gt;         &lt;br /&gt;
Ponente:          &lt;/strong&gt;&lt;/u&gt;&lt;strong&gt;Luis Ruiz Pavón&lt;/strong&gt;&lt;strong&gt; (Spenta - Beezy)&lt;/strong&gt; - miembro y fundador de AUGES (&lt;a href="http://www.auges.org/"&gt;www.auges.org&lt;/a&gt;) y uno de los grandes colaboradores de la comunidad de desarrolladores. Puedes seguirlo a través de su blog técnico (&lt;a href="http://www.luisruizpavon.com/"&gt;www.luisruizpavon.com&lt;/a&gt;) y de Twitter (@luisruizpavon).&lt;/blockquote&gt;Como siempre, se trata de un Webcast de asistencia es gratuita al que podéis registraros a través de la siguiente dirección:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032499034&amp;amp;Culture=es-ES" title="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032499034&amp;amp;Culture=es-ES"&gt;https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032499034&amp;amp;Culture=es-ES&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
En resumen, se trata de un evento que no deberíais perderos si queréis construir aplicaciones y componentes ASP.NET mejor estructurados, flexibles, desacoplados, muy mantenibles y fáciles de probar usando pruebas unitarias. &lt;br /&gt;
&lt;br /&gt;
Esperamos veros por allí ;-)&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-3479158616767085156?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QhgFZtxAY2qc4CmoNPvNhgrJWKs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QhgFZtxAY2qc4CmoNPvNhgrJWKs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QhgFZtxAY2qc4CmoNPvNhgrJWKs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QhgFZtxAY2qc4CmoNPvNhgrJWKs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=ZCiWfrqDgac:JDtd_d0yc34:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=ZCiWfrqDgac:JDtd_d0yc34:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=ZCiWfrqDgac:JDtd_d0yc34:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=ZCiWfrqDgac:JDtd_d0yc34:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/ZCiWfrqDgac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/3479158616767085156/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=3479158616767085156" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3479158616767085156?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3479158616767085156?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/ZCiWfrqDgac/auges-inyeccion-de-dependencias-en.html" title="[Auges] Inyección de dependencias en ASP.NET" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-qKrmbmN3Pxc/Tu3nLlCIkYI/AAAAAAAABtA/wzH0hWHjv0k/s72-c/logoauges%25255B4%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/auges-inyeccion-de-dependencias-en.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08NSHw7eSp7ImA9WhRQGEk.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-6955694693750250405</id><published>2011-12-14T09:04:00.000+01:00</published><updated>2011-12-14T09:04:59.201+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-14T09:04:59.201+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desarrollo" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><category scheme="http://www.blogger.com/atom/ns#" term="trucos" /><title>ASP.NET MVC: establecer el foco en un control al cargar la página</title><content type="html">&lt;img align="right" alt="ASP.NET MVC" border="0" height="77" src="http://lh6.ggpht.com/-77TUEegb-So/TrBGhEW5K3I/AAAAAAAABpw/cCe0D9c3bTQ/ASPNETMVC%25255B2%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ASP.NET MVC" width="142" /&gt;Uno de los aspectos más criticados por los desarrolladores cuando comienzan a trabajar con ASP.NET MVC es el hecho de tener que volver a resolver problemas que estaban ya más que solucionados en Webforms. &lt;br /&gt;
&lt;br /&gt;
Y uno de estos casos es un detallito muy simple pero útil: establecer el foco de edición en un control concreto al cargar una página. En Webforms era suficiente con asignar al atributo &lt;code&gt;defaultFocus&lt;/code&gt; del tag &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; el nombre del control que nos interesara, y ya lo teníamos solucionado; ASP.NET MVC no trae ninguna solución “de serie” para conseguirlo, aunque, como veremos en este post, no es mucho más complicado que la alternativa Webforms una vez hemos preparado la infraestructura necesaria.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
En líneas generales, la solución consiste en utilizar un pequeño script que, una vez cargada la página, mueva el foco hacia el control que nos interese. Por ejemplo, si quisiéramos que el campo con identificador “Nombre” obtenga el foco automáticamente, podríamos utilizar jQuery de la siguiente forma:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: blue;"&gt;function&lt;/span&gt; () {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&lt;span style="color: maroon;"&gt;"#Nombre"&lt;/span&gt;).focus();
&amp;nbsp;&amp;nbsp;&amp;nbsp; });
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;script&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue; font-size: 10pt;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Aunque eficaz, es una solución demasiado trabajosa e introduce una dependencia en el código, difícilmente manejable, hacia el nombre del control. Si quisiéramos introducir este código en múltiples puntos de nuestra aplicación tendríamos que copiar y pegar en cada vista, y sustituir el &lt;code&gt;id&lt;/code&gt; del control apropiado en cada caso, lo cual es bastante incómodo.&lt;br /&gt;
&lt;br /&gt;
¿No podríamos mejorar esto un poco?&lt;br /&gt;
&lt;h3&gt;








El helper SetFocusTo()&lt;/h3&gt;
Una posible solución, realmente rápida de implementar, sería crear un helper personalizado, al que llamaremos &lt;code&gt;SetFocusTo()&lt;/code&gt;,&amp;nbsp; que genere el código por nosotros partiendo únicamente de la información de la propiedad a editar.&lt;br /&gt;
&lt;br /&gt;
Y para evitar la dependencia hacia el nombre de la propiedad y hacerlo más flexible, incluso podríamos crear la versión fuertemente tipada del mismo, de forma que podamos utilizarlo de cualquiera de las siguientes formas:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: #008040;"&gt;// Usando el nombre de la propiedad:&lt;/span&gt;
&lt;span style="background-attachment: scroll; background-image: none; background-repeat: repeat repeat;"&gt;&lt;span style="background-color: yellow;"&gt;@&lt;/span&gt;&lt;/span&gt;Html.SetFocusTo(&lt;span style="color: #a31515;"&gt;"Nombre"&lt;/span&gt;)

&lt;span style="color: #008040;"&gt;// Usando la versión fuertemente tipada:&lt;/span&gt;
&lt;span style="background-attachment: scroll; background-image: none; background-repeat: repeat repeat;"&gt;&lt;span style="background-color: yellow;"&gt;@&lt;/span&gt;&lt;/span&gt;Html.SetFocusTo(model=&amp;gt;model.Nombre)&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
El código del helper es el siguiente:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlHelpers&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt; SetFocusTo&amp;lt;TModel, TProperty&amp;gt;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlHelper&lt;/span&gt;&amp;lt;TModel&amp;gt; html,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TModel, TProperty&amp;gt;&amp;gt; expression)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; prop = &lt;span style="color: #2b91af;"&gt;ExpressionHelper&lt;/span&gt;.GetExpressionText(expression);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; html.setFocusTo(prop);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt; SetFocusTo(&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlHelper&lt;/span&gt; html, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; propertyName)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; prop = &lt;span style="color: #2b91af;"&gt;ExpressionHelper&lt;/span&gt;.GetExpressionText(propertyName);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; html.setFocusTo(prop);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt; setFocusTo(&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;HtmlHelper&lt;/span&gt; html, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; property)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; id = html.ViewData.TemplateInfo.GetFullHtmlFieldId(property);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; script = &lt;span style="color: #a31515;"&gt;"&amp;lt;script type='text/javascript'&amp;gt;"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"$(function() {"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"$('#"&lt;/span&gt; + id + &lt;span style="color: #a31515;"&gt;"').focus();"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"});"&lt;/span&gt; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515;"&gt;"&amp;lt;/script&amp;gt;"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;MvcHtmlString&lt;/span&gt;.Create(script);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Recordad que para que estos helpers estén visible en las vistas y podáis usarlos normalmente, debéis incluir el espacio de nombres en el que están definidos bien sea añadiendo una directiva &lt;code&gt;@using&lt;/code&gt; en la vista, o bien en la sección &lt;code&gt;&amp;lt;namespaces&amp;gt;&lt;/code&gt; del archivo &lt;em&gt;web.config&lt;/em&gt; que encontraréis en la carpeta &lt;em&gt;/Views&lt;/em&gt; (o en la del área correspondiente).&lt;br /&gt;
&lt;br /&gt;
¡Y eso es todo! De esta forma tan simple, ya volvemos a disponer de la posibilidad de establecer el foco por defecto sobre un control de forma muy rápida, compacta, y cómoda de utilizar.&lt;br /&gt;
&lt;br /&gt;
Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-6955694693750250405?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MwGoiFjrav9OsL3uIbFPNtjiLhM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MwGoiFjrav9OsL3uIbFPNtjiLhM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MwGoiFjrav9OsL3uIbFPNtjiLhM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MwGoiFjrav9OsL3uIbFPNtjiLhM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=gJaQgj-Qbk4:HMFPsBnRkAk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=gJaQgj-Qbk4:HMFPsBnRkAk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=gJaQgj-Qbk4:HMFPsBnRkAk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=gJaQgj-Qbk4:HMFPsBnRkAk:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/gJaQgj-Qbk4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/6955694693750250405/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=6955694693750250405" title="8 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/6955694693750250405?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/6955694693750250405?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/gJaQgj-Qbk4/aspnet-mvc-establecer-el-foco-en-un.html" title="ASP.NET MVC: establecer el foco en un control al cargar la página" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-77TUEegb-So/TrBGhEW5K3I/AAAAAAAABpw/cCe0D9c3bTQ/s72-c/ASPNETMVC%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/aspnet-mvc-establecer-el-foco-en-un.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUNSX04fSp7ImA9WhRXEkw.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-3128258828908645068</id><published>2011-12-13T09:23:00.000+01:00</published><updated>2011-12-18T14:18:18.335+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-18T14:18:18.335+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="colaboraciones" /><category scheme="http://www.blogger.com/atom/ns#" term="óscar" /><title>Funciones constructoras en Javascript</title><content type="html">&lt;div class="invitado"&gt;&lt;div class="datos"&gt;&lt;h2 class="bloggerinvitado"&gt;  Blogger invitado&lt;/h2&gt;&lt;a href="http://www.variablenotfound.com/p/formulario-de-contacto.html"&gt;&lt;img alt="Blogger invitado" border="0" height="73" src="http://lh6.ggpht.com/-4HyIjIhR_2c/TomfdXCPZoI/AAAAAAAABoI/qI5chbQKIl0/image%25255B2%25255D.png?imgmax=800" title="image" width="73" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;  Óscar Sotorrío Sánchez&lt;/h2&gt;&lt;h3&gt;  Desarrollador independiente, MCP C#&lt;/h3&gt;Eterno aprendiz en esto de las tecnologías .NET y en especial con ASP.NET. Admirador de la filosofía de Internet y entusiasta de los nuevos modelos de negocio que rigen este mundillo.&lt;br /&gt;
Blog: &lt;a href="http://oscarsotorrio.com/"&gt;oscarsotorrio.com&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;En un artículo anterior vimos una pequeña introducción de los &lt;a href="http://www.variablenotfound.com/2011/10/objetos-en-javascript.html"&gt;objetos en JavaScript&lt;/a&gt; en el que se mostraron algunas características esenciales de los objetos en sí mismos. Continuamos ahora hablando de objetos y profundizando un poco en algunos conceptos.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Como ya sabemos, en la programación orientada a objetos (POO) es habitual tratar con los conceptos de encapsulación, herencia y polimorfismo. Puede que haya autores, y por qué no, también lectores, que tengan sus reservas a la hora de considerar JavaScript como un lenguaje totalmente orientado a objetos. La intención de este artículo no es entrar en este tipo de polémicas, pero lo que sí podemos considerar es que JavaScript, como hemos visto anteriormente, &lt;strong&gt;soporta objetos y hace una simulación muy personal de otros conceptos como clases o herencia&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
JavaScript &lt;strong&gt;no tiene una notación formal de clase&lt;/strong&gt; y recurre a las &lt;strong&gt;funciones constructoras para este fin&lt;/strong&gt;. Mencionar también que JavaScript utiliza los &lt;strong&gt;prototipos de los objetos para propagar la herencia&lt;/strong&gt;, algo que sin duda cuesta entender al principio y al que dedicaremos un artículo independiente más adelante.&lt;br /&gt;
&lt;h3&gt;  Función constructora&lt;/h3&gt;Una función constructora es una función normal y corriente de JavaScript que se utiliza para definir una especie de plantilla para nuestros objetos personalizados. Veamos un ejemplo:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente(nombre, fecha, direccion) {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._nombre = nombre;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._fechaNacimiento = fecha;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._direccion = direccion;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Como podemos observar, se trata de una típica función de JavaScript que admite una serie de parámetros de entrada aunque &lt;strong&gt;estos no son obligatorios en absoluto&lt;/strong&gt;. La única particularidad de esta función es que se utiliza la palabra reservada &lt;strong&gt;this&lt;/strong&gt; de JavaScript para definir una serie de propiedades (también podrán ser métodos) que formarán parte de nuestros objetos personalizados.&lt;br /&gt;
&lt;br /&gt;
&lt;img align="right" alt="Uso de la función constructora, y ayuda de Intellisense" border="0" height="257" src="http://lh6.ggpht.com/-MnXXNwv6HM0/TuJqtWEOHvI/AAAAAAAABsI/LwNlWhJqsz4/image5.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Uso de la función constructora, y ayuda de Intellisense" width="333" /&gt;En la ilustración lateral vemos cómo podemos utilizar esta función constructora para crear instancias de nuestros objetos personalizados.&lt;br /&gt;
&lt;br /&gt;
El operador &lt;code&gt;new&lt;/code&gt; utilizado junto a una función de JavaScript es lo que nos permite obtener un objeto constructor o función constructora. Lo que sucede por debajo es que &lt;code&gt;new&lt;/code&gt; primeramente crea un objeto sin propiedades y posteriormente llama a la función pasándole el nuevo objeto como valor de la palabra reservada &lt;code&gt;this&lt;/code&gt;&lt;strong&gt;.&lt;/strong&gt; Finalmente, la función nos devuelve un nuevo objeto con las propiedades y métodos definidos dentro de la constructora.&lt;br /&gt;
&lt;br /&gt;
Como se aprecia en el intellisense de la imagen observamos que el nuevo objeto &lt;code&gt;miCliente&lt;/code&gt; tiene todas las propiedades definidas anteriormente dentro del constructor.&lt;br /&gt;
&lt;br /&gt;
Como hemos comentado, no es necesario que el constructor tome parámetros, podemos crear una plantilla en blanco e ir rellenando los objetos con datos cuando lo necesitemos:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Constructor vacío&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente() {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._nombre;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._fechaNacimiento;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._direccion;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Creamos el objeto y le asignamos valores&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; cliente = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Cliente();
&amp;nbsp;&amp;nbsp;&amp;nbsp; cliente._nombre = &lt;span style="color: maroon;"&gt;"Cristina Rodriguez"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cliente._fechaNacimiento = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Date(1987, 3, 25);
&amp;nbsp;&amp;nbsp;&amp;nbsp; cliente._direccion = &lt;span style="color: maroon;"&gt;"Plaza Bilbao 25"&lt;/span&gt;;
&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Cuando hablamos de los objetos en JavaScript, vimos que se podían definir por medio de la notación JSON. Pues bien, también podemos definir objetos por medio de una función que devuelva un literal de objeto. En este caso, la función constructora hace de envoltorio para el código JSON de definición del objeto permitiéndonos reutilizar el código para crear distintas instancias del mismo:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente(nombre, fecha, direccion) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _nombre: nombre,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _fechaNacimiento: fecha,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _direccion: direccion
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Debemos tener en cuenta que siempre que utilicemos un &lt;code&gt;return&lt;/code&gt; dentro de una función constructora, el objeto devuelto &lt;strong&gt;ocultará al resto de miembros&lt;/strong&gt; que intentamos definir. No importa si la función devuelve un objeto literal, una cadena, un número, etc. Esto siempre ocultará a los demás miembros públicos que hayamos definido:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente(nombre, fecha, direccion, email) {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._email = email;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _nombre: nombre,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _fechaNacimiento: fecha,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _direccion: direccion
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;En este ejemplo cabría esperar que un objeto creado a partir de esta función constructora tuviera 4 propiedades públicas, pero no es así. La propiedad &lt;code&gt;email&lt;/code&gt; queda oculta por el objeto que se devuelve con &lt;code&gt;return&lt;/code&gt;, por lo que obtendríamos un objeto idéntico al del ejemplo anterior.&lt;br /&gt;
&lt;h3&gt;  Miembros de instancia&lt;/h3&gt;Las propiedades y métodos definidos dentro de la función constructora se pueden denominar miembros de instancia dado que cada objeto creado a partir de la función constructora guardará su propia copia de los miembros definidos. Veamos ahora cómo podemos diferenciar entre miembros de instancia públicos y privados.&lt;br /&gt;
&lt;br /&gt;
Hace unos instantes hemos definido una serie de &lt;strong&gt;propiedades públicas&lt;/strong&gt; en nuestros objetos por medio de variables JavaScript y la palabra reservada &lt;code&gt;this&lt;/code&gt;. Para definir métodos públicos procederemos de la misma forma, con la salvedad de que utilizaremos una función de JavaScript. También podemos definir &lt;strong&gt;propiedades y métodos privados&lt;/strong&gt; al objeto simplemente definiendo variables y funciones JavaScript dentro de la función constructora utilizando el &lt;code&gt;var &lt;/code&gt;de toda la vida. Es decir, para definir miembros públicos utilizaremos &lt;code&gt;this&lt;/code&gt; y para los miembros privados utilizaremos &lt;code&gt;var&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Veamos un ejemplo de código simplificado para clarificar todo esto.&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente(nombre, fecha, direccion) {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Propiedades privadas&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; edad;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Métodos privados&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; calcularEdad = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; actual = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Date().getYear();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; nacimiento = fecha.getYear();
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (actual &amp;lt;= nacimiento)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edad = &lt;span style="color: maroon;"&gt;"Error: no se ha podido calcular"&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edad = actual - nacimiento;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Propiedades públicas&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._nombre = nombre;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._fechaNacimiento = fecha;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._edad = edad;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._direccion = direccion;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Métodos públicos&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._presentarse = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calcularEdad();
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.write(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: maroon;"&gt;"Hola, mi nombre es "&lt;/span&gt; + &lt;span style="color: blue;"&gt;this&lt;/span&gt;._nombre + 
                &lt;span style="color: maroon;"&gt;" y tengo "&lt;/span&gt; + &lt;span style="color: blue;"&gt;this&lt;/span&gt;._edad + &lt;span style="color: maroon;"&gt;" años."&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Existen autores, como &lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt;, que hacen una pequeña distinción entre métodos públicos y métodos privilegiados. Esta distinción se basa en el hecho de que existe otra forma de definir métodos públicos en los objetos por medio del prototipo de la función constructora. Ya hemos comentado que hablaremos de los prototipos en otro artículo cuando hablemos también de la herencia.&lt;br /&gt;
&lt;br /&gt;
Pero para los impacientes les adelanto que con &lt;strong&gt;métodos privilegiados&lt;/strong&gt; se refiere precisamente a los métodos definidos dentro del cuerpo de la función con la&lt;strong&gt; palabra reservada &lt;code&gt;this&lt;/code&gt;&lt;/strong&gt;, dado que estos métodos tienen el privilegio de tener acceso a las variables y métodos privados. Mientras que los métodos definidos&lt;strong&gt; por medio del prototipo&lt;/strong&gt; de la función constructora no tendrán nunca este acceso o privilegio y son denominados simplemente &lt;strong&gt;métodos públicos&lt;/strong&gt;. Podéis leer sobre esta original idea en &lt;a href="http://www.crockford.com/javascript/private.html"&gt;este artículo&lt;/a&gt; escrito por el propio Crockford.&lt;br /&gt;
&lt;br /&gt;
Creo que es importante mencionar también que &lt;strong&gt;desde un método privado no tendremos acceso directo a miembros públicos&lt;/strong&gt;. Esto es así porque como hemos comentado anteriormente &lt;code&gt;this&lt;/code&gt; hace referencia al objeto devuelto por la función constructora y para la función privada este objeto se encuentra fuera de ámbito. De hecho, existe una solución a este aparente inconveniente que pasa por utilizar una potente característica de JavaScript, los &lt;strong&gt;closures&lt;/strong&gt;, que estudiaremos a fondo en otra ocasión. Veamos ahora qué sucede si intentamos el acceso directo:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Constructor(msjPrivado, msjPublico) {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; propiedadPrivada = msjPrivado;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.propiedadPublica = msjPublico;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; metodoPrivado = &lt;span style="color: blue;"&gt;function&lt;/span&gt; () {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(propiedadPrivada);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.propiedadPublica);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.metodoPublico = &lt;span style="color: blue;"&gt;function&lt;/span&gt; () {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metodoPrivado();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; obj = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Constructor(&lt;span style="color: maroon;"&gt;"mensaje privado"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"mensaje público"&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; obj.metodoPublico();&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Cuando ejecutemos este código recibiremos dos alertas, aunque una de ellas, la que intenta mostrar el valor de la propiedad pública nos notificará un &lt;code&gt;undefined&lt;/code&gt;. Es aún peor si intentamos acceder a la propiedad pública sin la sentencia &lt;code&gt;this&lt;/code&gt;, directamente tendremos un error del tipo variable no definida.&lt;br /&gt;
&lt;h3&gt;  Miembros estáticos&lt;/h3&gt;Los miembros estáticos o también llamados miembros de clase son &lt;strong&gt;aquellos estados o comportamientos comunes a todas las instancias de la clase&lt;/strong&gt;. En estos casos puede tener mucho más sentido no definirlos dentro de la función constructora, dado que todas las instancias de los objetos creadas a partir de ella contendrán una copia de estos miembros que son comunes a todos los objetos creados.&lt;br /&gt;
&lt;br /&gt;
Supongamos que en nuestro ejemplo &lt;code&gt;Cliente&lt;/code&gt; queremos tener una propiedad que almacene el IVA que se les va aplicar a todos nuestros clientes sin excepción.&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente() {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Definimos los miembros de instancia...&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Definimos una propiedad estática&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Cliente.IVA = 18;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//En otro punto del código hacemos uso del IVA&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; total = neto + (neto * (Cliente.IVA / 100));&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Igualmente, si tenemos un método que devuelva siempre el mismo objeto o valor, deberíamos definirlo a nivel de la función constructora. Este podría ser el caso de un método que devuelva una instancia de inicialización con valores por defecto para nuestro objeto &lt;code&gt;Cliente&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Si es la primera vez que el lector se asoma a la programación de objetos con JavaScript puede resultarle extraño este proceder, pero muchos objetos nativos de JavaScript siguen este criterio. Por ejemplo, el objeto &lt;code&gt;Number&lt;/code&gt; utiliza una propiedad estática que devuelve el mayor número posible en JavaScript, &lt;code&gt;Number.MAX_VALUE&lt;/code&gt;. Y el objeto &lt;code&gt;Date&lt;/code&gt; utiliza un método estático para analizar una fecha en formato cadena y devolver su representación en milisegundos desde una fecha siempre constante en JavaScript, &lt;code&gt;Date.parse(string)&lt;/code&gt;.&lt;br /&gt;
&lt;h3&gt;  Comprobar la función constructora de un objeto&lt;/h3&gt;Todos los objetos de JavaScript, ya sean nativos o de usuario, tienen una &lt;strong&gt;propiedad &lt;code&gt;constructor&lt;/code&gt;&lt;/strong&gt; que heredan del objeto genérico &lt;code&gt;Object&lt;/code&gt;, la cual hace referencia a la &lt;strong&gt;función constructora que inicializa el objeto&lt;/strong&gt; lo que en principio (ahora veremos por qué digo esto) nos permite determinar la función constructora de un objeto, y casi por extensión, la clase de éste:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; Cliente() {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Definición de miembros de Cliente...&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; unCliente = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Cliente();
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (unCliente.constructor == Cliente) {
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: darkgreen;"&gt;//Hacer algo con el objeto unCliente&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Por otro lado, también podríamos &lt;strong&gt;utilizar el operador &lt;code&gt;instanceof&lt;/code&gt; &lt;/strong&gt;para determinar la constructora de un objeto, pero con algunas diferencias. El operador &lt;code&gt;instanceof&lt;/code&gt; , a diferencia del anterior, comprueba la jerarquía del objeto, por lo tanto podríamos preguntar directamente sobre el objeto padre con idénticos resultados:&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Consolas; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; unCliente &lt;span style="color: blue;"&gt;instanceof&lt;/span&gt; Cliente &lt;span style="color: darkgreen;"&gt;// es true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt; &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; unCliente &lt;span style="color: blue;"&gt;instanceof&lt;/span&gt; Object&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: darkgreen;"&gt;// es true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Lamentablemente en JavaScript nada es tan sencillo como parece. Las cosas se complican cuando hablamos de modificar el prototipo de un objeto y la &lt;strong&gt;propiedad constructor&lt;/strong&gt; parece perder la referencia a la función constructora. Pero todo esto es harina de otro costal y se sale por completo de la intención de este artículo. Recomiendo al lector que lea &lt;a href="http://joost.zeekat.nl/constructors-considered-mildly-confusing.html"&gt;Constructors considered mildly confusing&lt;/a&gt; para comprender bien el comportamiento de la propiedad &lt;code&gt;constructor&lt;/code&gt; y el operador &lt;code&gt;instanceof&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Y para complicar más la cosa, también tenemos a nuestra disposición el &lt;strong&gt;operador unitario &lt;code&gt;typeof&lt;/code&gt;&lt;/strong&gt;. De nuevo, recomiendo a los lectores interesados en profundizar en estos temas los artículos &lt;a href="http://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/"&gt;The Secret Life of JavaScript Primitives&lt;/a&gt; y &lt;a href="http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/"&gt;Fixing the JavaScript typeof operator&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Autor: Óscar Sotorrío Sánchez &lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-3128258828908645068?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FuJJou29SqZvbmm0DAvTjUcOMa0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FuJJou29SqZvbmm0DAvTjUcOMa0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FuJJou29SqZvbmm0DAvTjUcOMa0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FuJJou29SqZvbmm0DAvTjUcOMa0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=1im7oYOCfY8:YJJc0jN2v1Q:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=1im7oYOCfY8:YJJc0jN2v1Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=1im7oYOCfY8:YJJc0jN2v1Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=1im7oYOCfY8:YJJc0jN2v1Q:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/1im7oYOCfY8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/3128258828908645068/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=3128258828908645068" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3128258828908645068?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/3128258828908645068?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/1im7oYOCfY8/funciones-constructoras-en-javascript.html" title="Funciones constructoras en Javascript" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-4HyIjIhR_2c/TomfdXCPZoI/AAAAAAAABoI/qI5chbQKIl0/s72-c/image%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/funciones-constructoras-en-javascript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYEQHsyfip7ImA9WhRQFkU.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-2125857979459688763</id><published>2011-12-12T09:55:00.000+01:00</published><updated>2011-12-12T09:55:01.596+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-12T09:55:01.596+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 63</title><content type="html">Esta semana no he tenido tiempo para ir publicando en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; los habituales links, pero sí que he podido recopilar algunos, así que ahí van los hallazgos realizados del 4 al 11 de diciembre de 2011. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.simple-talk.com/dotnet/.net-framework/asp.net-mvc-routing-extensibility/"&gt;ASP.NET MVC Routing Extensibility&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Simone Chiaretta &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://christianheilmann.com/2011/12/06/that-javascript-not-available-case/"&gt;That “JavaScript not available” case&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Christian Heilmann &lt;/li&gt;
&lt;li&gt;&lt;a href="http://woorkup.com/2011/12/05/jquery-1-7-visual-cheat-sheet/"&gt;&lt;strong&gt;jQuery 1.7 Visual Cheat Sheet&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Antonio Lupetti &lt;/li&gt;
&lt;li&gt;&lt;a href="http://codeclimber.net.nz/archive/2011/12/07/Set-the-AsyncTimeout-attribute-for-your-async-controllers.aspx"&gt;&lt;strong&gt;Set the AsyncTimeout attribute for your async controllers&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simone Chiaretta &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://hadihariri.com/2011/12/07/providing-intellisense-navigation-and-more-for-custom-helpers-in-asp-net-mvc/"&gt;Providing Intellisense, Navigation and more for Custom Helpers in ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Hadi Hariri &lt;/li&gt;
&lt;li&gt;&lt;a href="http://freshbrewedcode.com/jonathancreamer/2011/12/08/qunit-layout-for-javascript-testing-in-asp-net-mvc3/" title="Permanent Link to QUnit layout for JavaScript testing in ASP.net MVC3"&gt;&lt;strong&gt;QUnit layout for JavaScript testing in ASP.net MVC3&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Jonathan Creamer &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.bipinjoshi.net/articles/b0a33a0e-b4c2-43db-9f54-8de55c105fce.aspx"&gt;HTML5 Form features you should know&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Bipin Joshi &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/sergiotarrillo/archive/2011/12/07/codesnipeet-usar-el-atributo-obsolete-net-obsoleteattribute-class.aspx"&gt;Usar el atributo Obsolete (.NET: ObsoleteAttribute Class)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Sergio Tarrillo &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lontivero/archive/2011/12/08/como-crear-un-profiler-para-net.aspx"&gt;Como crear un Profiler para .Net&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Lucas Ontivero &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/jyeray/archive/2011/12/08/windows-phone-7-5-inserciones-masivas-en-sql-server-ce-vs-sql-server-vs-mongodb.aspx"&gt;[Windows Phone 7.5] Inserciones masivas en SQL Server CE vs SQL Server vs MongoDb&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;Josué Yeray &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://css-tricks.com/15151-public-service-announcement-careful-with-your-nested-border-radii/"&gt;Public Service Announcement: Careful With Your Nested Border-Radii&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Chris Coyier &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.impressivewebs.com/css-vertical-align/"&gt;Understanding CSS’s vertical-align Property&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Louis Lazaris &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.beletsky.net/2011/12/inside-aspnet-mvc-instantiation-of.html"&gt;&lt;strong&gt;Inside ASP.NET MVC: Instantiation of Controller&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Alexander Beletsky &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2011/12/05/what-s-the-difference-remainder-vs-modulus.aspx"&gt;&lt;strong&gt;What's the difference? Remainder vs Modulus&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Eric Lippert &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://code-inside.de/blog-in/2011/12/02/avoid-duplicate-content-with-iis7-domain-with-or-without-www"&gt;Avoid “Duplicate Content” with IIS7 – Domain with or without www&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Code Inside Team &lt;/li&gt;
&lt;li&gt;&lt;a href="http://tympanus.net/codrops/2011/12/05/lateral-on-scroll-sliding-with-jquery/"&gt;&lt;strong&gt;Lateral On-Scroll Sliding with jQuery&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Mary Lou &lt;/li&gt;
&lt;li&gt;&lt;a href="http://haacked.com/archive/2011/12/05/nuget_org_update.aspx"&gt;&lt;strong&gt;New NuGet.org Deployed!&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Phil Haack &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=776"&gt;Custom Validation in ASP.NET MVC 3 using DataAnnotationsModelValidator&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Mahesh Sabnis &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/gperez/archive/2011/12/07/b-250-squedas-de-texto-con-mongodb-y-vb-net-asp-net-webform.aspx"&gt;Búsquedas de Texto con MongoDB y VB.NET ASP.NET Webform&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Gonzalo Pérez &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blackwasp.co.uk/MACAddress.aspx"&gt;&lt;strong&gt;Obtaining a MAC Address&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;BlackWasp &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lruiz/archive/2011/12/07/video-asp-net-vnext-instalando-paquetes-con-nuget.aspx"&gt;[Vídeo] ASP.NET vNext - Instalando paquetes con Nuget&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Luis Ruiz &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/elbruno/archive/2011/12/05/unity-trabajando-con-singleton-utilizando-unity.aspx"&gt;Trabajando con Singleton utilizando UNITY&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Bruno Capuano &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lruiz/archive/2011/12/05/video-asp-net-vnext-strongly-typed-data-controls.aspx"&gt;[Vídeo] ASP.NET vNext - Strongly Typed Data Controls&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Luis Ruiz &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2011/12/05/ravendb-ii-los-documentos.aspx"&gt;RavenDB II: Los documentos&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Unai Zorrilla &lt;/li&gt;
&lt;li&gt;&lt;a href="http://codeclimber.net.nz/archive/2011/12/02/Lucene-net-2-9-4-is-out-now-with-NuGet.aspx"&gt;&lt;strong&gt;Lucene.net 2.9.4 is out, now with NuGet&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simone Chiaretta &lt;/li&gt;
&lt;li&gt;&lt;a href="http://speakingin.net/2011/12/05/mejoras-del-editor-de-css-en-visual-studio/"&gt;&lt;strong&gt;Mejoras del editor de CSS en Visual Studio&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Scott Guthrie (traducido por Juan Laó) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.blackwasp.co.uk/GetBaseException.aspx"&gt;Getting a Base Exception&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;BlackWasp &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2011/12/01/ravendb-i-empezamos.aspx"&gt;RavenDB I: Empezamos&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Unai Zorrilla &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que habitualmente podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-2125857979459688763?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/isiVcz7b8P4KlRr2GOjli1MeChA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/isiVcz7b8P4KlRr2GOjli1MeChA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/isiVcz7b8P4KlRr2GOjli1MeChA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/isiVcz7b8P4KlRr2GOjli1MeChA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Mse4RnqOv_M:c8CkV4ckaoo:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Mse4RnqOv_M:c8CkV4ckaoo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=Mse4RnqOv_M:c8CkV4ckaoo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=Mse4RnqOv_M:c8CkV4ckaoo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/Mse4RnqOv_M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/2125857979459688763/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=2125857979459688763" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/2125857979459688763?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/2125857979459688763?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/Mse4RnqOv_M/enlaces-interesantes-63.html" title="Enlaces interesantes 63" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/enlaces-interesantes-63.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUCQXo4fCp7ImA9WhRQEEo.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-7067329082302946961</id><published>2011-12-05T10:11:00.000+01:00</published><updated>2011-12-05T10:11:00.434+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-05T10:11:00.434+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 62</title><content type="html">Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 28 se noviembre al 3 de diciembre de 2011. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;  &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/lruiz/archive/2011/12/01/video-asp-net-vnext-smart-tasks-y-generaci-243-n-de-eventos-de-controles-desde-la-vista-html.aspx"&gt;&lt;strong&gt;Vídeo: ASP.NET vNext - Smart Tasks y generación de eventos de controles desde la vista HTML&lt;/strong&gt;&lt;/a&gt;      &lt;br /&gt;Luis Ruiz&lt;/li&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/gperez/archive/2011/12/02/tutorial-mongodb-con-asp-net-mvc-ejemplo-pr-225-ctico.aspx"&gt;&lt;strong&gt;Tutorial MongoDB con ASP.NET MVC - Ejemplo Práctico&lt;/strong&gt;&lt;/a&gt;      &lt;br /&gt;Gonzalo Pérez&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.jquery4u.com/tutorials/jquery-infinite-scrolling-demos/"&gt;5 jQuery Infinite Scrolling Demos&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;jQuery4u (vía @etnassoft) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://es.scribd.com/doc/74482487/Subete-a-La-Nube-de-Microsoft-Parte-3-Windows-Azure-AppFabric"&gt;Disponible una nueva entrega del libro GRATUITO de Azure : AppFabric y WIF&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Vía @ibonilm &lt;/li&gt;
&lt;li&gt;&lt;a href="http://css3generator.com/"&gt;&lt;strong&gt;Generador de CSS3&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Vía @boagworld &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://net.tutsplus.com/articles/editorials/why-many-developers-hate-asp-net-and-why-they-are-wrong/"&gt;Why Many Developers Hate ASP.NET… and Why They’re Wrong&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jeremy McPeak &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hanselman.com/blog/ScottHanselmans2011UltimateDeveloperAndPowerUsersToolListForWindows.aspx"&gt;&lt;strong&gt;Scott Hanselman's 2011 Ultimate Developer and Power Users Tool List for Windows&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Scott Hanselman &lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/shijuvarghese/archive/2011/12/01/building-a-windows-azure-app-using-azure-queue-azure-table-and-asp-net-mvc-web-role.aspx"&gt;&lt;strong&gt;Building a Windows Azure App using Azure Queue, Azure Table and ASP.NET MVC Web Role&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Shiju Varghese &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://mvccontrolstoolkit.codeplex.com/"&gt;ASP.NET MVC Controls Toolkit 1.5.5 released and available to download&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Vía @campusmvp &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.hanselman.com/blog/NewASPNETWebsiteLaunched.aspx"&gt;New ASP.NET website launched&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Scott Hanselman &lt;/li&gt;
&lt;li&gt;&lt;a href="http://omegaluz.wordpress.com/2011/12/01/unobtrusive-jquery-ui/"&gt;&lt;strong&gt;Unobtrusive jQuery UI with AJAX support&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Andy Cohen &lt;/li&gt;
&lt;li&gt;&lt;a href="http://devstand.com/2011/11/29/html5-tricks/"&gt;&lt;strong&gt;25 Amazing HTML5 Tricks and How to Make Them&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;DevStand &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://css-tricks.com/15276-the-script-tag/"&gt;The Script Tag&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Chris Coyier &lt;/li&gt;
&lt;li&gt;&lt;a href="http://freshbrewedcode.com/jonathancreamer/2011/11/29/global-handleerrorattribute-in-asp-net-mvc3/" title="Permanent Link to Global HandleErrorAttribute in ASP.net MVC3"&gt;&lt;strong&gt;Global HandleErrorAttribute in ASP.net MVC3&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Jonathan Creamer &lt;/li&gt;
&lt;li&gt;&lt;a href="http://panicoenlaxbox.blogspot.com/2011/11/de-vuelta-lo-basico-codificar-html.html" title="De vuelta a lo básico, codificar html, javascript y url"&gt;&lt;strong&gt;De vuelta a lo básico, codificar html, javascript y url&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Sergio León &lt;/li&gt;
&lt;li&gt;&lt;a href="http://codeclimber.net.nz/archive/2011/11/30/Web-API-preview-6-is-out-how-to-get-a.aspx"&gt;&lt;strong&gt;Web API preview 6 is out: how to get a RESTful mind&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Simone Chiaretta &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/2011/Nov/30/jQuery-Time-Entry-with-Time-Navigation-Keys"&gt;&lt;strong&gt;jQuery Time Entry with Time Navigation Keys&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Rick Strahl &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2011/11/30/ef-migrations-ef-4-3-y-que-nos-deparar-225-el-futuro.aspx"&gt;EF Migrations, EF 4.3 y que nos deparará el futuro&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Unai Zorrilla &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2011/11/29/code-first-migrations-beta-1-released.aspx"&gt;Code First Migrations: Beta 1 Released&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;ADO.NET Team &lt;/li&gt;
&lt;li&gt;&lt;a href="http://speakingin.net/2011/12/01/1197/" title="La cuarta preview the IE10"&gt;&lt;strong&gt;La cuarta preview the IE10&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Juan Laó &lt;/li&gt;
&lt;li&gt;&lt;a href="http://yeblon.com/the-craziest-javascript-implementations"&gt;&lt;strong&gt;The craziest Javascript implementations&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Vía @etnassoft &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeproject.com/KB/aspnet/CustomActionMethodSelectr.aspx"&gt;Custom Action Method Selector in MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Jigar Bagadai &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/ie/archive/2011/11/29/html5-for-applications-the-fourth-ie10-platform-preview.aspx"&gt;HTML5 for Applications: The Fourth IE10 Platform Preview&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;IEBlog &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/pwelter34/archive/2011/11/29/entity-framework-batch-update-and-future-queries.aspx"&gt;Entity Framework Batch Update and Future Queries&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Paul Welter (vía @osotorrio) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://mrubino.net/2011/11/29/vistas-view-engines-en-asp-net-mvc/"&gt;&lt;strong&gt;Vistas y View Engines en ASP.NET MVC&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Marc Rubiño &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.maartenballiauw.be/post/2011/11/29/Techniques-for-real-time-client-server-communication.aspx" title="Techniques for real-time client-server communication on the web (SignalR to the rescue)"&gt;&lt;strong&gt;Techniques for real-time client-server communication on the web (SignalR to the rescue)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Maarten Balliauw &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://speakingin.net/2011/11/29/uso-de-idisposable/"&gt;Uso de IDisposable&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Juan Laó &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.estoyenlanube.com/appfabric-service-bus-test-client/"&gt;AppFabric Service Bus Test Client&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ibon Landa &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.estoyenlanube.com/storage-queues-vs-service-bus-queues/"&gt;Storage Queues vs Service Bus queues&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ibon Landa &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.estoyenlanube.com/relayed-messagins-y-brokered-messaging/"&gt;Relayed Messaging y Brokered Messaging&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Ibon Landa &lt;/li&gt;
&lt;li&gt;&lt;a href="http://jmalarcon.es/post/Y-si-todo-lo-que-haces-llevara-tu-nombre-grabado.aspx"&gt;&lt;strong&gt;¿Y si todo lo que haces llevara tu nombre grabado?&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.codeproject.com/KB/scripting/HowToWritePluginInJQuery.aspx"&gt;How To Write a Plugin in jQuery&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Shakeel Iqbal &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/aspnet/GoogleMapsAPIV3ASPNET.aspx"&gt;&lt;strong&gt;Google Maps API V3 for ASP.NET&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;S V Sai Chandra (vía @osotorrio) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://haacked.com/archive/2011/11/28/departing-microsoft.aspx"&gt;Phil Haack deja Microsoft&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Phil Haack &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/11/27/Writing-a-Fluent-ASP-NET-MVC-Recursive-TreeView-Helper.aspx"&gt;&lt;strong&gt;Writing a Fluent ASP.NET MVC Recursive TreeView Helper&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Matt Hidinger &lt;/li&gt;
&lt;li&gt;&lt;a href="http://dailydotnettips.com/2011/11/24/css-editor-hierarchical-indentation-in-visual-studio-2011-developer-preview/" title="CSS Editor Hierarchical Indentation in Visual Studio 2011 Developer Preview"&gt;&lt;strong&gt;CSS Editor Hierarchical Indentation in Visual Studio 2011 Developer Preview&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Abhijit Jana &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.blackwasp.co.uk/TaskCancellation.aspx"&gt;Task Cancellation&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;BlackWasp &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.returngis.net/2011/11/anadir-dlls-en-la-gac-de-las-maquinas-de-windows-azure/" title="Permanent Link to Añadir dlls en la GAC de las máquinas de Windows Azure"&gt;&lt;strong&gt;Añadir dlls en la GAC de las máquinas de Windows Azure&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Gisela Torres &lt;/li&gt;
&lt;li&gt;&lt;a href="http://odetocode.com/Blogs/scott/archive/2011/11/24/composing-entity-framework-fluent-configurations.aspx"&gt;&lt;strong&gt;Composing Entity Framework Fluent Configurations&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;K. Scott Allen &lt;/li&gt;
&lt;li&gt;&lt;a href="http://speakingin.net/2011/11/30/nuevo-soporte-de-empaquetado-y-minificacion-asp-net-4-5/"&gt;&lt;strong&gt;Nuevo soporte de Empaquetado y Minificación (ASP.NET 4.5)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Juan Laó &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/11/27/new-bundling-and-minification-support-asp-net-4-5-series.aspx"&gt;New Bundling and Minification Support (ASP.NET 4.5 Series)&lt;/a&gt; &lt;/strong&gt;      &lt;br /&gt;Scott Guthrie (&lt;a href="http://speakingin.net/2011/11/30/nuevo-soporte-de-empaquetado-y-minificacion-asp-net-4-5/"&gt;traducido por Juan Laó&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://haacked.com/archive/2011/11/26/razor-donut-caching.aspx" title="Title of this entry"&gt;&lt;strong&gt;Razor Donut Caching&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Phil Haack &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-7067329082302946961?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GqcdHLkgzAhxkx1xCTwOw_ktyOE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GqcdHLkgzAhxkx1xCTwOw_ktyOE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GqcdHLkgzAhxkx1xCTwOw_ktyOE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GqcdHLkgzAhxkx1xCTwOw_ktyOE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=DMciYpfLufc:cgMiA8H-Rgg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=DMciYpfLufc:cgMiA8H-Rgg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=DMciYpfLufc:cgMiA8H-Rgg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=DMciYpfLufc:cgMiA8H-Rgg:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/DMciYpfLufc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/7067329082302946961/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=7067329082302946961" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7067329082302946961?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/7067329082302946961?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/DMciYpfLufc/enlaces-interesantes-62.html" title="Enlaces interesantes 62" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/12/enlaces-interesantes-62.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8ARXc6eyp7ImA9WhRQF0o.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-8791253269684790852</id><published>2011-11-29T10:31:00.000+01:00</published><updated>2011-12-13T11:40:44.913+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-13T11:40:44.913+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desarrollo" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="aspnetmvc" /><title>Mamá, ¿de dónde vienen los metadatos?</title><content type="html">&lt;img align="right" alt="ASPNETMVC" border="0" height="77" src="http://lh6.ggpht.com/-eGZZHEG7fcQ/TtJh_2zMagI/AAAAAAAABq4/FlRCYNTeoYc/ASPNETMVC2.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ASPNETMVC" width="142" /&gt;En ASP.NET MVC normalmente &lt;strong&gt;utilizamos atributos para aportar información adicional a las propiedades del Modelo&lt;/strong&gt;, incluyendo detalles como su descripción textual, formato de presentación, tipo de datos, etc. Esta información puede ser utilizada desde la capa vista para generar etiquetas, editores y, en algunos casos, incluso lógica de edición o presentación en la página.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, los atributos en el propio código de la clase no son la única vía para especificar metadatos en el framework. En este post veremos cómo &lt;strong&gt;extender el framework para crear nuevas vías para especificar &lt;/strong&gt;esta información.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h3&gt;



1. Proveedores de metadatos&lt;/h3&gt;
Como decíamos, ASP.NET MVC viene de fábrica con componentes que nos permiten introducir anotaciones directamente sobre las propiedades de las clases que manejamos. En el siguiente ejemplo podemos ver una entidad en la que se están introduciendo metadatos según este mecanismo:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Display&lt;/span&gt;(Name=&lt;span style="color: #a31515;"&gt;"Full name"&lt;/span&gt;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; FullName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;.EmailAddress)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Display&lt;/span&gt;(Name = &lt;span style="color: #a31515;"&gt;"Email address"&lt;/span&gt;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; EmailAddress { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;.Url)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Display&lt;/span&gt;(Name = &lt;span style="color: #a31515;"&gt;"Blog url"&lt;/span&gt;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; BlogUrl { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Display&lt;/span&gt;(Name=&lt;span style="color: #a31515;"&gt;"Birth year"&lt;/span&gt;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; BirthYear { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Cuando el framework necesita obtener los metadatos relativos a una clase, utiliza un &lt;em&gt;metadata provider&lt;/em&gt;, un componente que se encarga de obtener los metadatos desde donde se encuentren definidos. El proveedor usado por defecto se llama &lt;code&gt;DataAnnotationsModelMetadataProvider&lt;/code&gt;, y es el responsable de leer los atributos desde la definición de la clase, pero podemos sustituirlo fácilmente por otro proveedor que obtenga los metadatos desde otros orígenes, como archivos de configuración, bases de datos, o simplemente introducir lógica durante la generación de los mismos.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://lh5.ggpht.com/-yPEzhtU58bc/TtJiAuTgBmI/AAAAAAAABrA/G8PkaeSNtig/image3.png?imgmax=800" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img align="right" alt="ModelMetadata" border="0" height="532" src="http://lh5.ggpht.com/-yPEzhtU58bc/TtJiAuTgBmI/AAAAAAAABrA/G8PkaeSNtig/image3.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; margin-top: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ModelMetadata" width="198" /&gt;&lt;/a&gt;Sea cual sea su origen, los metadatos siempre se representan como objetos del tipo &lt;code&gt;ModelMetadata&lt;/code&gt;, cuya estructura podéis ver a la derecha. Los providers deben incluir la lógica para obtener los metadatos desde donde corresponda, pero siempre retornarán objetos &lt;code&gt;ModelMetadata&lt;/code&gt;, en los que, entre otra información, podemos encontrar los siguientes datos:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;descripción del elemento, &lt;/li&gt;
&lt;li&gt;cadena de formato cuando es visualizado, &lt;/li&gt;
&lt;li&gt;tipo de datos que contiene (emails, urls, fechas, horas, etc.), &lt;/li&gt;
&lt;li&gt;orden en el que debe aparecer la propiedad si se generan interfaces de edición o visualización de la entidad, &lt;/li&gt;
&lt;li&gt;representación textual para los nulos, &lt;/li&gt;
&lt;li&gt;si el dato es obligatorio, o de sólo lectura, &lt;/li&gt;
&lt;li&gt;si debe ser mostrado en edición, o en visualización, &lt;/li&gt;
&lt;li&gt;la plantilla de edición o visualización que debe utilizarse, &lt;/li&gt;
&lt;li&gt;… y muchos más. Podéis consultar la &lt;a href="http://msdn.microsoft.com/es-es/library/system.web.mvc.modelmetadata.aspx"&gt;referencia completa en MSDN&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;
Es importante tener en cuenta que &lt;strong&gt;el proveedor es invocado una vez para obtener los metadatos de la clase en sí, y otra vez por cada una de sus propiedades&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
¿Y cómo determina el framework MVC qué proveedor de metadatos utilizar? &lt;br /&gt;
&lt;br /&gt;
En primer lugar, intenta utilizar el &lt;em&gt;dependency resolver&lt;/em&gt; para obtener una instancia de un tipo que implemente &lt;code&gt;ModelMetadataProvider&lt;/code&gt; , que es la clase base para todos los proveedores. Este punto de extensión permite definir un proveedor personalizado muy fácilmente, y sobre todo si utilizamos contenedores IoC.&lt;br /&gt;
&lt;br /&gt;
Si no ha sido posible obtener un proveedor desde el &lt;em&gt;dependency resolver&lt;/em&gt;, el framework utilizará el establecido en la propiedad &lt;code&gt;ModelMetadataProviders.Current&lt;/code&gt;. Por defecto, esa propiedad contiene una un objeto de la clase &lt;code&gt;DataAnnotationsModelMetadataProvider&lt;/code&gt;, pero podemos sustituirlo por cualquier otro descendiente de &lt;code&gt;ModelMetadataProvider&lt;/code&gt; .&lt;br /&gt;
&lt;br /&gt;
Por tanto, para crear un proveedor personalizado de metadatos, basta con:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;crear una clase descendiente de &lt;code&gt;ModelMetadataProvider&lt;/code&gt; . Por comodidad, usaremos normalmente como base algunos de los siguientes tipos, más concretos:   &lt;ul&gt;
&lt;li&gt;&lt;code&gt;DataAnnotationsModelMetadataProvider&lt;/code&gt;, si lo que pretendemos es extender el sistema por defecto, basado en la captura de metadatos desde las anotaciones (atributos) de la clase. &lt;/li&gt;
&lt;li&gt;&lt;code&gt;AssociatedMetadataProvider&lt;/code&gt;, si lo que queremos es saltarnos por completo la obtención de metadatos desde la propia clase e implementar otros mecanismos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;indicar al framework que debe utilizar nuestro nuevo proveedor, que podemos hacerlo: &lt;ul&gt;
&lt;li&gt;o bien usando el &lt;em&gt;dependency resolver&lt;/em&gt;,&amp;nbsp;&lt;/li&gt;
&lt;li&gt;o bien estableciendo una instancia del nuevo provider en &lt;code&gt;ModelMetadataProviders.Current.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
Pero mejor veámoslo con un ejemplo…&lt;br /&gt;
&lt;h3&gt;



2. Creando un metadata provider&lt;/h3&gt;
Vamos a implementar un proveedor de metadatos sencillo con objeto de que podáis entender su funcionamiento.&lt;br /&gt;
&lt;br /&gt;
Como sabéis, al mostrar en una vista las etiquetas (labels) asociadas a una propiedad del Modelo, el texto que aparece es obtenido desde los metadatos de la entidad, desde el atributo &lt;code&gt;Display&lt;/code&gt; o &lt;code&gt;DisplayName&lt;/code&gt; (en ese orden); en caso de no existir, se asume como descripción el nombre de la propiedad.&lt;br /&gt;
&lt;br /&gt;
Pues bien, nuestro objetivo es conseguir generar de forma automática estas las descripciones (&lt;code&gt;DisplayName&lt;/code&gt;) de cada campo partiendo del nombre de la propiedad, y teniendo en cuenta el “camel casing”, de forma que podremos ahorrarnos el teclear esta descripción en muchos casos. Por ejemplo, a una propiedad que se llame &lt;code&gt;FullName&lt;/code&gt; se le asociará automáticamente la descripción “Full Name”, o &lt;code&gt;EmailAddress&lt;/code&gt; se describirá como “Email Address”. De esta forma la entidad anterior podremos simplificarla un poco:&lt;img align="right" alt="Resultado de EditorForModel() con la entidad Friend" border="0" height="263" src="http://lh5.ggpht.com/-DRvf3A3kUQ0/TtJiBmDYBcI/AAAAAAAABrE/AM7LiL7dG4o/image%25255B5%25255D.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Resultado de EditorForModel() con la entidad Friend" width="178" /&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; FullName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;.EmailAddress)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; EmailAddress { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;.Url)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; BlogUrl { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; BirthYear { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Fijaos que hemos eliminado los atributos &lt;code&gt;[Display]&lt;/code&gt;, y el resultado en ejecución de un editor de esta entidad se mostrará como en la captura de pantalla lateral, donde las etiquetas de cada campo han sido generadas automáticamente.&lt;br /&gt;
&lt;br /&gt;
Para ello, dado que queremos conservar el comportamiento del proveedor por defecto &lt;code&gt;DataAnnotationsModelMetadataProvider, &lt;/code&gt;lo extenderemos y añadiremos la lógica deseada a su método &lt;code&gt;CreateMetadata()&lt;/code&gt;, que es el invocado para obtener los metadatos de la entidad y cada una de las propiedades:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;DisplayNameModelMetadataProvider&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;DataAnnotationsModelMetadataProvider&lt;/span&gt;
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ModelMetadata&lt;/span&gt; CreateMetadata(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;Attribute&lt;/span&gt;&amp;gt; attributes, &lt;span style="color: #2b91af;"&gt;Type&lt;/span&gt; containerType,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt; modelAccessor, &lt;span style="color: #2b91af;"&gt;Type&lt;/span&gt; modelType, &lt;span style="color: blue;"&gt;string&lt;/span&gt; propertyName)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; metadata = &lt;span style="color: blue;"&gt;base&lt;/span&gt;.CreateMetadata(attributes, containerType,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; modelAccessor, modelType, propertyName);
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (metadata.PropertyName != &lt;span style="color: blue;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; metadata.DisplayName == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; metadata.DisplayName = splitCamelCase(metadata.PropertyName);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; metadata;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt; splitCamelCase(&lt;span style="color: blue;"&gt;string&lt;/span&gt; input)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Regex&lt;/span&gt;.Replace(input, &lt;span style="color: #a31515;"&gt;"([A-Z])"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;" $1"&lt;/span&gt;, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Text.RegularExpressions.&lt;span style="color: #2b91af;"&gt;RegexOptions&lt;/span&gt;.Compiled).Trim();
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
La implementación del método &lt;code&gt;CreateMetadata()&lt;/code&gt; no es nada del otro mundo:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;En primer lugar, llamamos a la clase antecesora para obtener los metadatos a partir de las anotaciones del modelo. &lt;/li&gt;
&lt;li&gt;A continuación, si no se ha obtenido ningún valor de metadatos para&amp;nbsp; el &lt;code&gt;DisplayName&lt;/code&gt;, y siempre que se esté evaluando una propiedad, la establecemos, generándola mediante el método &lt;code&gt;splitCamelCase()&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;El método &lt;code&gt;splitCamelCase()&lt;/code&gt; no tiene mucho misterio (bueno, sí, usa expresiones regulares ;-)), y lo único que hace es buscar las letras mayúsculas e insertar delante de ellas un espacio. Es algo tosco, pero me vale para no desviar la atención del post a este detalle sin importancia (y por cierto, el mérito de este método no es mío, sino &lt;a href="http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx"&gt;de Jon Galloway&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
Y esto es todo. Ahora vamos a registrar el proveedor para el framework pueda utilizarlo, y veremos cómo hacerlo de las dos formas que he comentado antes: de forma directa, y usando el &lt;em&gt;dependency resolver&lt;/em&gt;.&lt;br /&gt;
&lt;h4&gt;



2.1. Registro del proveedor directamente&lt;/h4&gt;
La fórmula más rápida y sencilla consiste en establecer directamente una instancia del nuevo proveedor en la propiedad &lt;code&gt;ModelMetadataProviders.Current&lt;/code&gt;, durante la inicialización de la aplicación, por ejemplo así:&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;    &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Application_Start()
    {
        &lt;span style="color: #2b91af;"&gt;AreaRegistration&lt;/span&gt;.RegisterAllAreas();
 
        &lt;span style="background-color: yellow;"&gt;&lt;span style="color: #2b91af;"&gt;ModelMetadataProviders&lt;/span&gt;.Current = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DisplayNameModelMetadataProvider&lt;/span&gt;();&lt;/span&gt;
 
        RegisterGlobalFilters(&lt;span style="color: #2b91af;"&gt;GlobalFilters&lt;/span&gt;.Filters);
        RegisterRoutes(&lt;span style="color: #2b91af;"&gt;RouteTable&lt;/span&gt;.Routes);
    }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Esto es todo lo que necesitamos hacer para que nuestro flamante proveedor entre en funcionamiento.&lt;br /&gt;
&lt;h4&gt;



2.2. Registro del proveedor usando el &lt;em&gt;dependency resolver&lt;/em&gt;&lt;/h4&gt;
Si estáis utilizando un contenedor de IoC, quizás sea más coherente introducir la resolución de este proveedor en el mismo.&lt;br /&gt;
&lt;br /&gt;
Cuando el framework intenta obtener el proveedor de metadatos actual, antes de nada intenta localizarlo utilizando el &lt;em&gt;dependency resolver&lt;/em&gt;. Si estamos utilizando un contenedor IoC como &lt;a href="http://unity.codeplex.com/"&gt;Unity&lt;/a&gt; o &lt;a href="http://structuremap.net/structuremap/"&gt;StructureMap&lt;/a&gt;, podemos utilizarlos para gestionar esta dependencia, asociando la clase abstracta &lt;code&gt;ModelMetadataProvider&lt;/code&gt; al tipo concreto &lt;code&gt;DisplayNameModelMetadataProvider&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, en el caso de Unity, lo más sencillo es instalar el paquete Unity.MVC3 desde Nuget, y ya simplemente tendríamos que incluir la siguiente línea en el registro de tipos (en el archivo &lt;em&gt;bootstrapper.cs&lt;/em&gt;):&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IUnityContainer&lt;/span&gt; BuildUnityContainer()
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; container = &lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;UnityContainer&lt;/span&gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: yellow;"&gt;container.RegisterType&amp;lt;&lt;span style="color: #2b91af;"&gt;ModelMetadataProvider&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;DisplayNameModelMetadataProvider&lt;/span&gt;&amp;gt;();&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterControllers();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; container;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
Una vez registrado el &lt;em&gt;provider&lt;/em&gt;, sea directamente o mediante este último mecanismo, el sistema obtendrá los metadatos desde éste. Así, tendríamos el siguiente resultado:&lt;br /&gt;
&lt;br /&gt;
&lt;table border="0" cellpadding="2" cellspacing="4"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td valign="top" width="266"&gt;&lt;strong&gt;Clase del Modelo&lt;/strong&gt;&lt;/td&gt;&lt;td valign="top" width="245"&gt;&lt;strong&gt;Vista&lt;/strong&gt;&lt;/td&gt;&lt;td valign="top" width="195"&gt;&lt;strong&gt;Resultado&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td valign="top" width="266"&gt;&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: 10pt;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Friend&lt;/span&gt;
{
 [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
 &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; FullName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }

 [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
 [&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;.EmailAddress)]
 &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; EmailAddress 
               { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 [&lt;span style="color: #2b91af;"&gt;Required&lt;/span&gt;]
 [&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;DataType&lt;/span&gt;.Url)]
 &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; BlogUrl { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
 
 &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; BirthYear { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;td valign="top" width="245"&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; overflow: visible; padding: 0px;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="background-attachment: scroll; background-image: none; background-repeat: repeat;"&gt;&lt;span style="background-color: yellow;"&gt;&lt;span style="font-size: 10pt;"&gt;@&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; (Html.BeginForm())
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-attachment: scroll; background-image: none; background-repeat: repeat;"&gt;&lt;span style="background-color: yellow;"&gt;@&lt;/span&gt;&lt;/span&gt;Html.EditorForModel()
 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;input&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="submit"&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;td valign="top" width="195"&gt;&lt;img alt="image" border="0" height="220" src="http://lh4.ggpht.com/-8EvGaKJchek/TtJiB-Z6k6I/AAAAAAAABrM/KqPjmFvlwNI/image%25255B10%25255D.png?imgmax=800" style="background-image: none; border-width: 0px; display: inline; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Resultado en tiempo de ejecución" width="149" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Puedes descargar el &lt;a href="https://skydrive.live.com/?cid=c3a43a99b617d787&amp;amp;sc=documents&amp;amp;uc=1&amp;amp;id=C3A43A99B617D787%21270#"&gt;proyecto de ejemplo (VS2010 + MVC 3) desde mi Skydrive&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
En definitiva, en este post hemos visto que &lt;strong&gt;en ASP.NET MVC los metadatos&lt;/strong&gt; no proceden de una ubicación fija, sino que &lt;strong&gt;son obtenidos a través de un proveedor&lt;/strong&gt; configurable. Esto nos permite modificar el comportamiento por defecto del framework y &lt;strong&gt;adaptarlo a nuestras necesidades&lt;/strong&gt;, generarlos de forma dinámica, como en el ejemplo que hemos visto, u obtenerlo desde algún almacén de persistencia (como podría ser un archivo de configuración o una bases de datos), y siempre de forma muy sencilla aprovechando la magnífica extensibilidad del marco de trabajo :-)&lt;br /&gt;
&lt;br /&gt;
Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-8791253269684790852?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/c4fW9ZRGO99TBrOTayJNSslaqes/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c4fW9ZRGO99TBrOTayJNSslaqes/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/c4fW9ZRGO99TBrOTayJNSslaqes/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c4fW9ZRGO99TBrOTayJNSslaqes/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=6RMNQFKZcJo:b4h8izeS9eY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=6RMNQFKZcJo:b4h8izeS9eY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=6RMNQFKZcJo:b4h8izeS9eY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=6RMNQFKZcJo:b4h8izeS9eY:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/6RMNQFKZcJo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/8791253269684790852/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=8791253269684790852" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/8791253269684790852?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/8791253269684790852?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/6RMNQFKZcJo/mama-de-donde-vienen-los-metadatos.html" title="Mamá, ¿de dónde vienen los metadatos?" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-eGZZHEG7fcQ/TtJh_2zMagI/AAAAAAAABq4/FlRCYNTeoYc/s72-c/ASPNETMVC2.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/11/mama-de-donde-vienen-los-metadatos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYCQX85cCp7ImA9WhRRFEs.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-5691445886714306112</id><published>2011-11-28T09:16:00.000+01:00</published><updated>2011-11-28T09:16:00.128+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-28T09:16:00.128+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="enlaces" /><title>Enlaces interesantes 61</title><content type="html">Estos son los enlaces publicados en &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt; y &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt; del 21 al 27 de noviembre de 2011. Espero que os resulten interesantes. :-)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blackrabbitcoder.net/archive/2011/11/24/c.net-little-wonders-the-predicate-comparison-and-converter-generic-delegates.aspx" title="Title of this entry"&gt;&lt;strong&gt;C#/.NET Little Wonders: The Predicate, Comparison, and Converter Generic Delegates&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
James Michael &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://deanhume.com/Home/BlogPost/mvc-data-uri-html-helper/61"&gt;MVC Data URI HTML Helper&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Dean Hume &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/pietrobr/archive/2011/11/24/lazy-remote-validation-with-asp-net-mvc-3.aspx"&gt;&lt;strong&gt;Lazy Remote Validation with ASP.NET MVC 3&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Pietro Brambati (vía @osotorrio) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.kunal-chowdhury.com/2011/11/download-free-ebook-razor-view-engine.html"&gt;Download Free eBook: Razor View Engine in MVC 3&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Abhimanyu Kumar Vatsa (vía @lluisfranco) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/b/ie/archive/2011/11/21/adding-personality-with-css3-transitions-and-animations.aspx"&gt;Adding Personality with CSS3 Transitions and Animations&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
IEBlog &lt;/li&gt;
&lt;li&gt;&lt;a href="http://odetocode.com/Blogs/scott/archive/2011/11/21/modernizr-js-polyfills.aspx"&gt;&lt;strong&gt;Modernizr.js: Polyfills&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
K. Scott Allen &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://weblogs.asp.net/manavi/archive/2011/03/27/associations-in-ef-4-1-code-first-part-1-introduction-and-basic-concepts.aspx"&gt;Associations in EF 4.1 Code First&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Morteza Manavi (vía @osotorrio) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.desarrolloweb.com/articulos/helpers-formularios-dotnet.html"&gt;&lt;strong&gt;Helpers para formularios (ASP.NET MVC)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Eduard Tomás (vía @JTorrecilla) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://learn.iis.net/page.aspx/1072/web-platform-installer-v4-command-line-webpicmdexe-preview-release/"&gt;Web Platform Installer v4 command line (WebPICMD.exe) Preview Release&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
WebPICmd Team (Vía @wasat) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dnmplus.net/articulos/microsoft-translator-api.aspx"&gt;Microsoft Translator API&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Juan María Laó (vía @lluisfranco) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.sciencenews.org/view/generic/id/336359/title/Coffee_delivers_jolt_deep_in_the_brain"&gt;Coffee delivers jolt deep in the brain&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Laura Sanders &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geekswithblogs.net/PhubarBaz/archive/2011/11/21/getting-query-parameters-in-javascript.aspx"&gt;&lt;strong&gt;Getting Query Parameters in Javascript&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Phubar Baz (!) &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://channel9.msdn.com/coding4fun/blog/Contour-Analysis-for-Image-Recognition-in-C"&gt;Contour Analysis for Image Recognition in C#&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Greg Duncan &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://hadihariri.com/2011/11/22/resharper-settings-in-61/"&gt;ReSharper Settings in 6.1&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Hadi Hariri &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.heikniemi.net/hardcoded/2011/10/whats-new-in-net-framework-4-5-poster/"&gt;Poster: What’s new in .NET Framework 4.5?&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Heikniemi Hardcoded &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/palvarez/archive/2011/11/22/roar-inserciones-masivas-en-mongodb-vs-sql-server-iv.aspx"&gt;Inserciones Masivas en MongoDB vs SQL Server (IV)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Pablo Doval &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/omarvr/archive/2011/11/22/ddd-2-framework-de-ioc-service-pack-1.aspx"&gt;&lt;strong&gt;DDD: 2- Framework de IoC (Service Pack 1)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Omar del Valle &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.etnassoft.com/2011/11/22/el-nuevo-objeto-jquery-callbacks/"&gt;&lt;strong&gt;El nuevo objeto jQuery $.Callbacks()&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Carlos Benítez &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.jquery.com/2011/11/21/jquery-1-7-1-released/"&gt;&lt;strong&gt;jQuery 1.7.1. released&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
jQuery Team &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kabytes.com/programacion/crear-un-archivo-zip-con-javascript/" title="Crear un archivo .ZIP con JavaScript"&gt;&lt;strong&gt;Crear un archivo .ZIP con JavaScript&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Pablo Suárez (vía @osotorrio) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://coding.smashingmagazine.com/2011/11/18/html5-semantics/"&gt;&lt;strong&gt;HTML5 Semantics&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Bruce Lawson &lt;/li&gt;
&lt;li&gt;&lt;a href="http://stephenwalther.com/blog/archive/2010/12/20/integrating-javascript-unit-tests-with-visual-studio.aspx"&gt;&lt;strong&gt;Integrating JavaScript Unit Tests with Visual Studio&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Stephen Walther &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/hh547101.aspx"&gt;Embedding RavenDB into an ASP.NET MVC 3 Application&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Justin Schwartzenberger &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/pnunez/archive/2011/11/21/aclarando-cqrs-traducci-243-n.aspx"&gt;Aclarando CQRS [traducción]&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Pablo Núñez &amp;amp; Co. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.sitepoint.com/asp-net-mvc-4-developer-preview-whats-new/"&gt;Task Support for Asynchronous Controllers in MVC 4&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Malcolm Sheridan &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/lruiz/archive/2011/11/21/fechas-utc-javascript-jquery-timeago-templates-y-dem-225-s-hierbas.aspx"&gt;Fechas UTC, JavaScript, jQuery timeago, templates y otras hierbas&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Luis Ruiz Pavón &lt;/li&gt;
&lt;li&gt;&lt;a href="http://panicoenlaxbox.blogspot.com/2011/11/hace-poco-he-tenido-la-necesidad-de.html"&gt;&lt;strong&gt;Saber si un elemento tiene un evento jQuery asignado&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Sergio León &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jasoft.org/Blog/post/Bloquear-los-botones-mientras-se-envia-un-formulario.aspx" title="Bloquear los botones mientras se envía un formulario"&gt;&lt;strong&gt;Bloquear los botones mientras se envía un formulario&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
José Manuel Alarcón &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.navegapolis.net/content/view/1045/49/"&gt;Agilismo Vs Modelo waterfall tradicional. Muy interesante y resumidito.&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Juan Palacio &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.dnmplus.net/articulos/desarrollo-de-una-aplicacion-metro-en-c-y-xaml.aspx"&gt;Desarrollo de una aplicación Metro en C# y XAML&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Eduard Tomás (vía @Jtorrecilla) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://speakerdeck.com/u/addyosmani/p/large-scale-javascript-application-architecture" title="http://speakerdeck.com/u/addyosmani/p/large-scale-javascript-application-architecture"&gt;&lt;strong&gt;Large-scale JavaScript Application Architecture&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Addy Osmani &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.wadewegner.com/2011/11/aggregating-rss-feeds-in-c-and-asp-net-mvc-3/"&gt;&lt;strong&gt;Aggregating RSS Feeds in C# and ASP.NET MVC 3&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Wade Wegner &lt;/li&gt;
&lt;li&gt;&lt;a href="http://uxmovement.com/thinking/6-tips-to-help-you-build-a-great-web-application/" title="6 Tips to Help You Build a Great Web Application"&gt;&lt;strong&gt;6 Tips to Help You Build a Great Web Application&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Greg &amp;amp; Adrian &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.etnassoft.com/2011/11/21/los-nuevos-metodos-jquery-on-y-off/" title="Enlace permanente a Los nuevos métodos jQuery on() y off()"&gt;Los nuevos métodos jQuery on() y off()&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Carlos Benítez &lt;/li&gt;
&lt;li&gt;&lt;a href="http://geeks.ms/blogs/omarvr/archive/2011/11/19/ddd-2-framework-de-ioc-parte-1.aspx"&gt;&lt;strong&gt;DDD: 2- Framework de IoC (parte 1)&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; y &lt;/strong&gt;&lt;a href="http://geeks.ms/blogs/omarvr/archive/2011/11/20/ddd-2-framework-de-ioc-parte-2.aspx" title="DDD- 2- Framework de IoC (parte 2)"&gt;&lt;strong&gt;DDD- 2- Framework de IoC (parte 2)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;
Omar del Valle &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/blogs/unai/archive/2011/11/20/hot-inserciones-masivas-en-sql-sersver-vs-mongo-db-iii.aspx"&gt;HOT:Inserciones masivas en Sql Sersver vs Mongo DB (III)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;
Unai Zorrilla &lt;/li&gt;
&lt;/ul&gt;
Y no olvidéis que podéis seguir esta información en vivo y en directo desde &lt;a href="http://www.facebook.com/variablenotfound"&gt;Variable not found en Facebook&lt;/a&gt;, o a través de &lt;a href="http://twitter.com/jmaguilar"&gt;Twitter&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Publicado en &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-5691445886714306112?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JmAd58qluhlPyVIwLOwbwiwnBNM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JmAd58qluhlPyVIwLOwbwiwnBNM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JmAd58qluhlPyVIwLOwbwiwnBNM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JmAd58qluhlPyVIwLOwbwiwnBNM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=UWylnVUAnzg:OfpeK8elkNs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=UWylnVUAnzg:OfpeK8elkNs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=UWylnVUAnzg:OfpeK8elkNs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=UWylnVUAnzg:OfpeK8elkNs:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/UWylnVUAnzg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/5691445886714306112/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=5691445886714306112" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/5691445886714306112?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/5691445886714306112?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/UWylnVUAnzg/enlaces-interesantes-60.html" title="Enlaces interesantes 61" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/11/enlaces-interesantes-60.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQHQ3k5eyp7ImA9WhRREEk.&quot;"><id>tag:blogger.com,1999:blog-27752126.post-4963577682904126935</id><published>2011-11-23T10:25:00.000+01:00</published><updated>2011-11-23T10:25:32.723+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-23T10:25:32.723+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="auges" /><category scheme="http://www.blogger.com/atom/ns#" term="eventos" /><title>[Auges] ASP.NET MVC + HTML5 + CSS3 + JQuery = La unión perfecta</title><content type="html">&lt;img align="right" alt="AUGES - ASP.NET User Group de España" border="0" height="49" src="http://lh6.ggpht.com/-yXAgbZraCZM/Tp7nc_Ac3YI/AAAAAAAABpo/NtaWN_Yqc58/logoauges2.png?imgmax=800" style="margin: 0px 0px 10px 10px;" title="AUGES - ASP.NET User Group de España" width="213" /&gt;Lo primero, para el que aún no lo sepa, &lt;strong&gt;se ha cancelado&lt;/strong&gt; por causas de fuerza mayor la charla de Luis Ruíz Pavón sobre &lt;strong&gt;inyección de dependencias en ASP.NET&lt;/strong&gt; que estaba prevista para el próximo martes 29 de noviembre. Sentimos las molestias que esto pueda causar, pero &lt;a href="http://twitter.com/#!/luisruizpavon/status/138602298262827008"&gt;lo primero es lo primero&lt;/a&gt; :-).&lt;br /&gt;
&lt;br /&gt;
Sin embargo, como ya teníamos el cuerpo hecho a aprender cosas interesantes la semana que viene, tendremos el placer de contar con el gran&amp;nbsp;&lt;strong&gt;Marc Rubiño&lt;/strong&gt;, MVP en ASP.NET y fundador de LoNetCamp, que nos mostrará el &lt;strong&gt;lunes 28 de noviembre a las 19:00h&lt;/strong&gt; (horario peninsular español) la potencia que aporta la unión de tecnologías como &lt;strong&gt;ASP.NET MVC, HTML5, CSS3 y JQuery&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Descripción del evento:&lt;br /&gt;
&lt;blockquote&gt;
&lt;h3&gt;



ASP.NET MVC + HTML5 + CSS3 + Jquery = La unión perfecta &lt;/h3&gt;
Las aplicaciones web modernas nos exigen cada vez más utilizar estándares para dotar a nuestra aplicación de una vistosidad y usabilidad nunca visto hasta el momento. Con ASP.NET MVC podemos separar las responsabilidades de nuestra aplicación de una forma sencilla y con HTML5 y CSS3 podemos obtener los mejores resultados independientemente del navegador gracias a librerías como modernizr.&lt;br /&gt;
&lt;br /&gt;
En este Webcast lo que veremos es cómo de una forma totalmente práctica y con Visual Studio 2010 podemos crear una aplicación web totalmente funcional.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;¿Qué utilizaremos en esta práctica?&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;ASP.NET MVC v.3:&lt;/strong&gt; Es una plataforma gratuita, Open Source y está incluida en .NET 4.0. Nos sirve para realizar aplicaciones ASP.NET utilizando el patrón MVC, separando las responsabilidades ofreciéndonos beneficios como desarrollo orientado a pruebas “TDD”, mejor soporte de SEO con URLs más limpias, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;HTML v.5:&lt;/strong&gt; La quinta revisión del veterano HTML no finalizada, pero los navegadores se han lanzado a una lucha frenética para adaptar sus especificaciones. Esta versión ha tenido en cuenta las nuevas necesidades y nos ofrece una web semántica.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;CSS3:&lt;/strong&gt; La tercera revisión de la hoja de estilos en cascada, que nos permite separar la estructura del documento de su presentación.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;JQuery:&lt;/strong&gt; Librería script que encapsula la complejidad de JavaScript y nos permite realizar animaciones, interactuar con el DOM y extender la aplicación de una manera muy sencilla y viene incluido en los proyectos ASP.NET MVC.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Modernizr: &lt;/strong&gt;Librería que nos permite validar si el navegador soporta alguna de las nuevas funcionalidades de HTML 5 y nos permite actuar en consecuencia. Para hacer nuestra aplicación realmente cross-browser.&lt;/blockquote&gt;
Como siempre, podéis asistir desde casa o el trabajo (es un Webcast online), y &lt;strong&gt;la asistencia al evento es totalmente gratuita&lt;/strong&gt;. Para acceder, simplemente debéis registraros en la siguiente dirección: &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032500294&amp;amp;Culture=es-ES" title="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032500294&amp;amp;Culture=es-ES"&gt;https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032500294&amp;amp;Culture=es-ES&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img align="right" alt="Mejora el rendimiento con Programación Paralela" border="0" height="156" src="http://lh3.ggpht.com/-IcPa-7Obw5g/TsvQvnMR_7I/AAAAAAAABqw/dcHlaH3JSTg/image%25255B12%25255D.png?imgmax=800" style="background-image: none; border: 0px currentColor; display: inline; float: right; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Mejora el rendimiento con Programación Paralela" width="211" /&gt;Ah, y los que ya teníais la fecha del 29 reservada para disfrutar con un Webcast de categoría, recordaros que ese mismo día podéis encontrar a&amp;nbsp;&lt;a href="http://twitter.com/lluisfranco"&gt;Lluis Franco&lt;/a&gt;, MVP C# y un fenómeno de la naturaleza,&amp;nbsp; hablando sobre &lt;a href="http://www.secondnug.com/EventosDesarrollo/tabid/57/Default.aspx"&gt;programación paralela en SecondNug&lt;/a&gt;, a las 19:30h (GMT+1).&lt;br /&gt;
&lt;br /&gt;
Buena semana de eventos tenemos por delante, ¿eh?&lt;br /&gt;
&lt;br /&gt;
Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;Variable not found&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27752126-4963577682904126935?l=www.variablenotfound.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xVOMQ0VlFv7lyRJMqyZKrRi_W34/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xVOMQ0VlFv7lyRJMqyZKrRi_W34/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xVOMQ0VlFv7lyRJMqyZKrRi_W34/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xVOMQ0VlFv7lyRJMqyZKrRi_W34/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=bS4P7iI-8oQ:KeTXcc5ct74:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=bS4P7iI-8oQ:KeTXcc5ct74:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?i=bS4P7iI-8oQ:KeTXcc5ct74:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/vnf?a=bS4P7iI-8oQ:KeTXcc5ct74:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/vnf/~4/bS4P7iI-8oQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.variablenotfound.com/feeds/4963577682904126935/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=27752126&amp;postID=4963577682904126935" title="4 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/4963577682904126935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/27752126/posts/default/4963577682904126935?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/vnf/~3/bS4P7iI-8oQ/auges-aspnet-mvc-html5-css3-jquery-la.html" title="[Auges] ASP.NET MVC + HTML5 + CSS3 + JQuery = La unión perfecta" /><author><name>José M. Aguilar</name><uri>http://www.blogger.com/profile/11683750380776435448</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/_O9D62hXq-ng/S6Hfc0RM0YI/AAAAAAAABOg/bEEA3DZ7Uac/S220/fb1.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-yXAgbZraCZM/Tp7nc_Ac3YI/AAAAAAAABpo/NtaWN_Yqc58/s72-c/logoauges2.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://www.variablenotfound.com/2011/11/auges-aspnet-mvc-html5-css3-jquery-la.html</feedburner:origLink></entry></feed>

