Si necesitamos tener un control checkbox en cada fila y que solo podamos seleccionar un sola fila a la vez (idem a un option)
Esto puede servir tanto para ASP.NET Webform como para MVC, con la salvedad de que depende de como renderizan las grillas de datos.
Gracias a una pregunta de los foros de MSDN de ASP.NET “Limitar selección Checkbox en GridView” tenia algo similiar en el borrador así que aquí va.
Si tenemos un Gridview con una columna template algo así:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Seleccion">
<ItemTemplate>
<asp:CheckBox ID="chkSeleccion" runat="server" CssClass="controlSeleccion" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Nombre" HeaderText="Nombre" />
<asp:BoundField DataField="FechaNacimiento" HeaderText="Fecha Nacimiento" />
</Columns>
</asp:GridView>
Cuando renderiza en ASP.NET 4.0 lo hace de esta manera
| La tabla HTML |
La celda con el control |
 |
 |
Solución con jQuery: Evento .click()
Podriamos tener un selector en jQuery que tome todos los checkbox que están dentro de nuestra clase “controlSeleccion” y cada vez que se realiza un evento click (con mouse o sin el directamente con el teclado igualmente dispara el evento)
<script type="text/javascript"> 1: $(function () { 2: $('.controlSeleccion input:checkbox').click(function () { 3: $('.controlSeleccion input:checkbox').removeAttr('checked'); 4: $(this).attr('checked', true); 5: });
6: });
</script>
NOTA: El selector :checkbox es identico a [type=checkbox]
Solución con jQuery: Atachando el evento con .on() (nuevo en jQuery 1.7)
En la version 1.7 de jQuery tenemos la sintaxis “.on()” para bindear a eventos (como lo eran live o bind, etc).
Nos quedaria algo asi para hacer lo anterior:
<script type="text/javascript"> 1: $(function () { 2: $('.controlSeleccion input:checkbox').on('click', function () { 3: $('.controlSeleccion input:checkbox').removeAttr('checked'); 4: $(this).attr('checked', true); 5: });
6: });
</script>
Para otros post:
Mas adelante escribiré como hacer que este checkbox se comporte como el “comando de selección del gridview”, para que nos quede todo “un poco mas elegante”, ya que en este caso particular el desarrollador deberá “iterar” para buscar que control esta seleccionado. Una mejora seria que este control este enlazado a algun campo booleano del la colección de objetos
Espero que les sirva de ayuda o guía.
Se acerca fin de año y por estos lugares, terminó un curso intensivo (y casi sin respiro) de estas tres tecnologías (WPF/WCF/Silverlight) en el marco de las Becas Control+F (@becascontrolf)
“Con el objetivo de fomentar más y mejor empleo en las áreas de software y tecnología a nivel nacional, el Ministerio de Trabajo, Empleo y Seguridad Social de la Nación, en conjunto con CESSI, y con el apoyo de empresas referentes del sector, ofrecen cursos de capacitación gratuita en todo el país.”
Esta vez se armaron en Corrientes, y los gestionó el Polo IT Corrientes a los cursos de Programación .NET Junior, .NET Senior, Administración en SQL Server y Genexus
Aquí los que rindieron el primer día, y los del segundo (a la derecha):

Algunos ya trabajaban con este tecnología o en .NET, pero la mayoría alumnos de entidades educativas de la región (UTN FRRe, UNNE, Institutos de IT) y por eso razón casi la mitad del curso quedo en el grupo de los rezagados que quedaron por el camino (por falta de tiempo)
Mas fotos
Similares que tuve la oportunidad de estar al frente:
Mas info
Trabajando con Federico necesitamos realizar consultas a la DB “dinámicamente” para rellenar reportes con Report Server embebido en nuestras aplicaciones web.
Para eso utilizamos Procedimientos Almacenados, y como queremos que sea lo mas “genérico posible”, obtenemos el nombre del reporte (ya sea por un campo de la DB o armándolo con alguna política de nombres teniendo en cuenta el del reporte).
Como sabemos la Cadena de Conexión de Entity Framework esta compuesta por la cadena, path de archivos del modelo y de asignación. Por ejemplo…
<connectionStrings>
<add name="AdventureWorksEntities"
connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />
</connectionStrings>
Para armar nuestro Comando ADO.NET “puro y simple” (y genérico para llenar nuestros reportes) necesitamos la Conexión y para ello una cadena… y no queríamos:
- Tener una cadena por separado (la tentación y fuerte!)
- Parsear la cadena de conexión de EF (para obtener la parte que necesitamos)
Entonces solo basta una lectura rápida de las propiedades de la conexión en este caso nos valemos de la propiedad StoreConnection del EntityConnection
Textual de MSDN:
(…)Proporciona acceso a la conexión de origen de datos subyacente usada por el objeto EntityConnection.(…)
Podríamos entonces tener una propiedad estática que nos ayude:
public static string ConnectionString
{
get
{
using ( AdventureWorksEntities contexto = new AdventureWorksEntities())
{
string cadenaCon =
((System.Data.EntityClient.EntityConnection)contexto.Connection).StoreConnection.ConnectionString;
return cadenaCon;
}
}
}
Enlaces
Si alguien quiere utilizar en una vista con Razor el caracter “@” en alguna función javascript y/o html por ejemplo, algo simple…
var indiceArroba = email.indexOf("@");
El mensaje que nos proporciona:
""" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.

O simplemente si quieres escribir en HTML un simple @

Con el mensaje:
A space or line break was encountered after the "@" character. Only valid identifiers, keywords, comments, "(" and "{" are valid at the start of a code block and they must occur immediately following "@" with no space in between.
Solución: El caracter escape para el @ es el doble @@
Para poder seguir adelante el carácter escape para el @ es simplemente el doble arroba @@ 
var indiceArroba = email.indexOf("@@");
<span>O si quieres simplemente escribir un @@ simple.</span>
NOTA: No esta demás comentar también que podemos combinar HTML/Client Scripting con código Razor utilizando @: y <text>, mas info aquí
Enlaces
Si estas accediendo a un SQL SERVER 2008 y utilizando uno de sus nuevos tipos de datos como el Time veras que no es fácil leerlo con un SqlDataReader. La idea es obtener el valor del Time (SQL) que en .NET es un tipo de dato TimeSpan.
Si estas pensando hacer esto! olvídalo…
TimeSpan tiempo = (TimeSpan)reader["tiempo"];
Ir a las fuentes (ayuda a MSDN)
Investigando un poco di con método GetTimeSpan del SqlDataReader
Para los curiosos:
Si utilizas el tipo de dato Time(de SQL 2008) se mapea a un tipo de datos TimeSpan de .NET.
Si vemos el articulo Asignar tipos de datos de SQL Server (ADO.NET) vemos que para obtener este valor tenemos un método GetDateTime del SqlDataReader
Pero luego descubrí el GetTimeSpan
Obteniendo el valor de campo Time…
- Para obtener el valor del Time (SQL) que en .NET es un tipo de dato TimeSpan utilizamos el método GetTimeSpan del SqlDataReader, que recibe la posición de la columna, si es la columna 3, el índice es 2... ejemplo:
TimeSpan horaTimeSpan = reader.GetTimeSpan(2);
- Podemos mejorar agregando el método GetOrdinal para obtener el índice de la columna si tenemos el nombre
TimeSpan horaTimeSpan = reader.GetTimeSpan(reader.GetOrdinal("hora"));
hora.Text = horaTimeSpan.ToString("HH:mm");
NOTA 1: Como dice la ayuda en MSDN se debería antes verificar si IsDBNull la columna del reader o sino la conversión genera una excepción
NOTA 2: Dar formato al TimeSpan “para que quede legible por nosotros, los humanos” ;)
Espero que te sirva de ayuda o guía.
Enlaces

Es grato recibir buenas noticias por correo! Y mas si es un premio.
Dear Jose,
Congratulations! We’re pleased to inform you that your contributions to Microsoft online technical communities have been recognized with the Microsoft Community Contributor Award.
The Microsoft Community Contributor Award is reserved for participants who have made notable contributions in Microsoft online community forums such as TechNet, MSDN and Answers. The value of these resources is greatly enhanced by participants like you, who voluntarily contribute your time and energy to improve the online community experience for others.
Becoming a Microsoft Community Contributor Award recipient includes access to important benefits, such as complimentary resources to support you in your commitment to Microsoft online communities…
Thank you for your commitment to Microsoft online technical communities and congratulations again!
Uno día a día esta con el “cotidiano fuego de los proyectos” y se hace tiempo para ayudar y seguir aprendiendo en los foros… donde cada uno aporta un granito de arena, para que entre todos podamos crecer y evangelizar en la tecnología que nos apasiona (y nos da dolores de cabeza).
Asi que los invito a los foros de MSDN, TechNet y Answers, para compartir, preguntar, ayudar o simplemente “mirar pasivamente”.
Gracias a Microsoft por el reconocimiento… y también por el premio; ya que además de la “distinción” tenemos acceso a una librería online con muchos libros de Microsoft Press (E-Reference Library de Safari Book Online) así que no hay impedimento para seguir formándose…
Es grato ver en Geeks.ms que Javier Torrecilla y Josué Yeray Julián Ferreiro también tienen este honor… y es mas honor para mi compartir con ellos.

Por una pregunta sobre este tema “Enviar datos a una forma dentro de un iframe”, desempolve algo que tenia en borrador hace años…
ANTES NADA… Por qué lo tenia en borrador?
Pense que nadie lo necesitaba… Porque trabajar con iFrames en ASP.NET Webforms en “un dolor constante”, hay que hacer cosas con javascript para la comunicación… una tema fácil es incrustar desde ASP.NET contenido en iframes, y otra es enviar-recibir información. Todo esto porque la magia es ASP.NET es tener un solo formulario que casi casi no debes “tocarlo”
(NOTA: en ASP.NET MVC es una maravilla trabajar con javascript, tienes un mejor control del HTML resultante)
En ASP.NET Webforms tenemos varias opciones a los iFrames para “cargar contenido”
Pero volvamos al tema de enviar datos a una iFrame dentro de la misma pagina…
El problema
Al problema que en los foros de MSDN preguntaron tenia era como eje esta misma temática así que aquí va para tenerla de referencia.
“Enviar datos a una forma dentro de un iframe”, que como sabemos en ASP.NET tenemos un solo formulario en las paginas, en cada postback se realiza un post a la misma pagina salvo que cambiemos en un boton por ejemplo la propiedad PostbackUrl para modificar la pagina donde enviara los datos… pero no podemos definir el target (nombre del frame) de donde queremos que cargue la pagina destino.
Solución
Para que funcione necesitamos en ASP.NET webforms o en cualquier otro formulario web modificar el atributo target del formulario
Solución en ASP.NET Webforms
Como modificamos la pagina de destino para enviar los datos? con la propiedad PostbackUrl.
Como modificamos el target del formulario? en el cliente lo tenemos que hacer al momento de realizar el click… del boton. Nos ayudamos con OnClientClick
Bueno para muestra “basta un botón” así que el ejemplo para descargar 
La pagina padre
Default.aspx
Ingrese un Nombre: <asp:TextBox ID="txtNombre" runat="server" ClientIDMode="Static"></asp:TextBox>
<asp:Button ID="btnAceptar" runat="server" Text="Aceptar" OnClientClick="enviarDatosAFrame('iframePaginaHija');" PostBackUrl="~/PaginaIframeDestino.aspx" />
<iframe id="iframePaginaHija" name="iframePaginaHija" src="PaginaIframeDestino.aspx" width="100%" height="200px"></iframe>
<p> </p>
<asp:Label ID="lblHora" runat="server" Text="lblHora"></asp:Label>
Si podemos ver el botón que es un webcontrol Button que tiene dos atributos definidos
- OnClientClick: Que nos ayuda a llamar a una funcion del lado del cliente antes de enviar el submit
- PostbackUrl: Nos ayuda a definir una pagina de destino diferente a la actual cuando se realice el submit
Tenemos un script llamado “enviarDatosAFrame” que es una función del lado del cliente en javascript que nos ayuda a cambiar el atributo target del formulario de ASP.NET
<script type="text/javascript">
function enviarDatosAFrame(frameNombre) {
var formulario = document.getElementById('form1');
formulario.target = frameNombre;
setTimeout('formularioInicializar(\'' + formulario.id + '\');', 2000);
}
</script>
Mas adelante vemos que es el formularioInicializar.
NOTA: Para que nos sirva de esta manera que buscamos el formulario por Id (getElementById), debes tener definido el Id del formulario de ASP.NET (de tu pagina o MasterPage)
La pagina destino (el contenido del iframe)
PaginaIframeDestino.aspx (en el ejemplo)
Nombre: <asp:Label ID="lblNombre" runat="server" Text="lblNombre"></asp:Label>
<p> </p>
<asp:Label ID="lblHora" runat="server" Text="lblHora"></asp:Label>
Tengo definido en la pagina la directiva PreviousPageType para tener intellisense de lo voy a obtener de la pagina padre
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PaginaIframeDestino.aspx.cs" Inherits="PaginaIframeDestino" %>
<%@ PreviousPageType VirtualPath="~/Default.aspx" %>
En el codebehind…
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
//Sin el atributo de pagina PreviousPageType
//TextBox txt = (TextBox)PreviousPage.FindControl("txtNombre");
//string nombre = txt.Text;
//Con el atributo de pagina PreviousPageType,
//tenemos acceso a intellisense de PreviousPage (que agregamos una propieddad publica)
string nombre = PreviousPage.Nombre;
lblNombre.Text = nombre;
}
lblHora.Text = DateTime.Now.ToLongTimeString();
}
NOTA en la pagina padre (default.aspx) tengo una propiedad para recuperarla en la destino
public partial class _Default : System.Web.UI.Page
{
public string Nombre {
get {
return txtNombre.Text;
}
}
...
Colocar el atributo target directamente en el form? por si lo pensaste colocar aquí…
Hacer esto significaría que todo postback de esa pagina tendrá como target el definamos “estáticamente allí”… si lo hacemos con javascript a este cambio será dinámico y solamente hay que agregar al control que hace el sumbit la funcionalidad de que ejecute, previo submit, el cambio de target

Con JQuery: Agregar funcionalidad no intrusiva en botón
Con la ayuda de jQuery podemos armar una función que nos ayude a la tarea de modificar el target del formulario a partir de la configuración de un botón si necesidad de adicionar OnClientClick sino simplemente configurando el botón con unos atributos
En este ejemplo, para probar los atributos data de jQuery, se me ocurrió utilizar data-FrameDestino para definir el nombre del iframe donde quiero enviar los datos y como todavía no se como es el selector para “data”, utilice un selector de clase css, entonces todos los botones con la clase “postbackToFrame” tendrán esta funcionalidad
El botón queda así:
<asp:Button ID="btnAceptarConjQuery" runat="server" Text="Aceptar (con jQuery)"
PostBackUrl="~/PaginaIframeDestino.aspx"
CssClass="postbackToFrame"
data-frameDestino="iframePaginaHija" />
La función jQuery
<script type="text/javascript">
$(document).ready(function () {
$(".postbackToFrame").click(function () {
var form = $(this).parents("form:first");
var formNombre = $(form).attr("id");
var frameNombre = $(this).data("frameDestino");
if (frameNombre != null || frameNombre != 'undefined') {
$(form).attr('target', frameNombre);
}
setTimeout('formularioInicializar(\'' + formNombre + '\');', 2000);
});
})
</script>
Mas adelante vemos que es el formularioInicializar…
Modificamos el target del form, pero las siguientes acciones toman el mismo camino. Como inicializamos?
Cuando modificamos en el cliente el target del formulario el mismo permanece allí y cualquier otra acción que involucre un postback se dirigirá al target correspondiente. Si en la pagina tenemos mas botones, linkbutton o cualquier control que realice un submit tomara el valor del formulario que configuramos
Si llegamos a necesitar que el valor del target se inicialice debemos llamar a una función para tal motivo luego de un tiempo prudencial del submit, en mi caso 2000 milisegundos
Con jQuery
<script type="text/javascript">
function formularioInicializar(formularioNombre) {
$('#' + formularioNombre).attr('target', '');
}
</script>
O como la primer versión con javascript puro.
<script type="text/javascript">
function formularioInicializar(formularioNombre) {
var form = document.getElementById(formularioNombre);
formt.target ='';
}
</script>
NOTA: Seria bueno este inicializar formulario reciba el target tambien y podemos unificar todas las funciones que modifican este atributo
Ejemplo para descargar
Espero que les sirva de ayuda o guía.
Como en los foros de MSDN alguien necesitaba de un tema similar, lo tenia en borrador y encontré el “justificativo” de terminarlo. Ahora lo tengo para referencias de “opciones de capturar la salida HTML”, encubriendo para minificar el HTML resultante.
Que es Compactar (Minify) HTML?
La idea es limpiar el HTML resultante de caracteres que no son necesarios para renderizar la pagina (espacios en blanco innecesarios, salto de línea) esto se llama Minificar (Minification) Por que son innecesarios estos caracteres? Solo están para una mejor lectura para nosotros “los mortales desarrolladores” la maquina no los necesita.. y el HTML tampoco :)
Aquí utilizare de sinónimo Minificar = Minimizar = Compactar
Puedes ver con un ejemplo online de esta tarea:
Veamos a “vista de águila”…
| Antes | Después |
 |  |
Se utiliza generalmente para los Javascript, y los CSS donde existen muchas herramientas online, incluso para .NET el Microsoft Ajax Minifier.
Es necesario compactar la salida HTML?
“No colocar todos los huevos en la misma canasta/cesta”
Depende… utilizando herramientas como YSlow o Page Speed no darán información en que lugar “ganamos más” optimizando. Y no siempre es en la compactación del HTML, ya que con la configuración de la Compresión HTTP (gzip) en el IIS es suficiente.
Entonces que tenemos que compactar?
Lo que si es necesario es comprimir, compactar y agrupar (son tres técnicas que en conjunto logran reducir tiempos deF descarga) los CSS y JS porque allí si ganamos en cantidad de archivos a descargar, como así también los CSS Sprites pero bueno eso ya es otro tema
Todo el mundo ya conoce que tenemos herramientas para estas tareas como por ejemplo Microsoft Ajax Minifier o YUI Compressor for .NET (u otras similares) Algunas con todas las características que necesitamos otras con menos.
Primero lo primero: Como modificamos el HTML resultante?
Si conocemos el ciclo de vida de una pagina ASP.NET, lo que se nos viene a la cabeza como lugar para realizar la acción es el método Render, por lo que hay que sobrescribirlo.
La idea la tome por aquí para obtener el HTML resultante, que era para quitar el Viewstate, así que nos sirve para este ejemplo.
Ahora el objetivo: Minimizar el HTML
Lo primero que se nos viene la cabeza es reemplazar cadenas, y allí el “balón de oro” es el que tenga mejor performance para cadenas inmutables ;)
Muy bueno este articulo: Comparing RegEx.Replace, String.Replace and StringBuilder.Replace – Which has better performance?
Pero además, vamos a necesitar si o si expresiones regulares (esos textos que como siempre digo parece que un Vulcano los haya escrito) para detectar algunos patrones que nos son simples de buscar. Entonces para el ejemplo RegEx.Replace. (perdonen pero hay que sufrir con esto de expresiones regulares)
Objetivos secundarios de este post
Vamos a ver opciones para modificar el HTML resultante para minimizarlo, las complicaciones que podamos tener y porque no es uno de los pilares de la optimización pero aunque no lo utilicemos veremos tecnicas que en alguna oportunidad nos pueden ayudar para otras tareas de modificar la salida:
- Modificar la salida de una pagina HTML
- Seguir
sufriendo utilizando con expresiones regulares y como nos ayudan bastante (aunque no las entendamos luego de 1 hora) - Utilizar los Response.Filter (Filtros para la salida)
- Conocer y ver una implementación (de terceros) de PageParserFilter
Que opciones tenemos para minimizar el HTML
- Sobrescribimos el método Render de una pagina, y “limpiamos” con expresiones regulares
- Sobrescribimos el método Render y limpiamos con componentes como el YUI Compressor for .NET
- Utilizamos la formidable clase en C# para minimizar CSS realizada por Michael Ash que es la que utiliza el YUI Compressor for .NET
- Un poco mas “técnicos”… Utilizamos Response.Filter
- Vamos hasta “al infinito y mas allá”. Utilizamos PageParserFilter.
Aqui nos ayudamos con un componente que ya lo tiene implementado - [Idea a futuro] Componente del IIS para limpiar caracteres en blanco… (no lo tengo implementado, si alguien tiene un ejemplo bienvenido en los comentarios)
OPCION 1: Sobrescribimos el método Render de una pagina, limpiamos con expresiones regulares
Aquí sobrescribimos el evento Render para obtener la cadena de salida y tratarla
protected override void Render(HtmlTextWriter writer)
{
//Obtemos el HTML resultante dentro de un TextWriter
TextWriter tw = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(tw);
//Renderizamos la pagina
base.Render(htmlWriter);
htmlWriter.Close();
//Obtenemos la cadena del HTML
string htmlResultante = tw.ToString();
//Limpiando
string htmlMin = YODA.Web.HTMLUtil.MinificarHTML(htmlResultante);
//Escribiendo la salida
writer.Write(htmlMin);
}
Haciendo uso de expresiones regulares simples podremos Minificar el HTML, solo para algunos patrones (espacios entre tags, saltos de linea, tabs, espacios en blanco mayores que 2
namespace YODA.Web
{
public class HTMLUtil
{
public HTMLUtil()
{
//
// TODO: Add constructor logic here
//
}
public static string MinificarHTML(string htmlCadena)
{
Regex regEspaciosEntreTags = new Regex(@">(?! )\s+", RegexOptions.Singleline);
Regex regSaltoDeLinea = new Regex(@"([\n\s])+?(?<= {2,})<", RegexOptions.Singleline);
Regex regSaltoDeLinea2 = new Regex(@"\r\n", RegexOptions.Singleline);
Regex regTabs = new Regex(@"\t", RegexOptions.Singleline);
Regex regEspaciosEnBlanco = new Regex(@"\s{2,}", RegexOptions.Singleline);
htmlCadena = regEspaciosEntreTags.Replace(htmlCadena, ">");
htmlCadena = regSaltoDeLinea.Replace(htmlCadena, "<");
htmlCadena = regSaltoDeLinea2.Replace(htmlCadena, string.Empty);
htmlCadena = regTabs.Replace(htmlCadena, string.Empty);
htmlCadena = regEspaciosEnBlanco.Replace(htmlCadena, string.Empty);
return htmlCadena.ToString();
}
}
}
Puedes buscar en regexlib.com algunos ejemplos. En el ejemplo para descargar dejo varias implementaciones.
NOTA IMPORTANTE: Este código no es del todo óptimo, pero sirve como ejemplo. Ya que espacios de variables en javascript var vble1 = “ valor 1”; lo optimiza por los espacios; Los saltos de linea no tiene en cuenta si lo que viene es una funcion js, y asi sucesivamente. Vuelvo a insistir, antes que el lector se acuerde de mi familia, que esto es un ejemplo de como modificar
OPCION 2: Sobrescribimos el método Render y limpiamos con componentes como el YUI Compressor for .NET

NOTA Opción 2: Aquí utilice el componente pero dentro del componente la clase que hace la magia de minimizar es un código de autoría de Michael Ash
Asi que lo dejo también dentro de ejemplo a descargar en la carpeta App_Code
NOTA: No podremos utilizar Microsoft Ajax Minifier solo tenemos dos métodos que nos nos ayudan a minimizar JS y CSS incluso de obuscar para minimizar el nombre de variables

Opcion 1.1, 2.1 (Tip): Heredar comportamiento (sobreescribir el Render en un solo lugar)
Ambas Opciones (1, 2) que sobrescriben el Render pueden estar en una Pagina Base para luego heredarla o en una Master base, como el ejemplo
namespace YODA.Web
{
public class MasterPageBase : System.Web.UI.MasterPage
{
public MasterPageBase()
{
//
// TODO: Add constructor logic here
//
}
protected override void Render(HtmlTextWriter writer)
{
//Obtemos el HTML resultante dentro de un TextWriter
TextWriter tw = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(tw);
//Renderizamos la pagina
base.Render(htmlWriter);
htmlWriter.Close();
//Obtenemos la cadena del HTML
string htmlResultante = tw.ToString();
//Limpiando
string htmlMin = YODA.Web.HTMLUtil.MinificarHTML(htmlResultante);
//Escribiendo salida
writer.Write(htmlMin);
}
}
}
hay que hacer que la Master de nuestro sitio herede de la MasterPageBase que creamos
public partial class SiteWithOverrrideRender : YODA.Web.MasterPageBase
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
Aqui debemos crear un filtro, que es una clase que hereda en este ejemplo de MemoryStream y realice las acciones correspondientes
“(…)Cuando se crea un objeto Stream y se establece la propiedad Filter para el objeto Stream, toda la salida HTTP enviada por Write pasa por el filtro.(…)”
namespace YODA.Web
{
public class MinificarHTMLFiltro : MemoryStream
{
public Stream HtmlStream { get; set; }
public MinificarHTMLFiltro(Stream htmlStream)
{
this.HtmlStream = htmlStream;
}
public override void Write(byte[] buffer, int offset, int count)
{
string contenidoEnElBuffer = UTF8Encoding.UTF8.GetString(buffer);
//Acciones a realizar
//Accion 1: Minificar salida limpinado tabs/espacios en blanco
contenidoEnElBuffer = YODA.Web.HTMLUtil.MinificarHTML3(contenidoEnElBuffer);
HtmlStream.Write(UTF8Encoding.UTF8.GetBytes(contenidoEnElBuffer), offset, UTF8Encoding.UTF8.GetByteCount(contenidoEnElBuffer));
}
}
}
Y lo utilizamos en el Load de la pagina, simple no?
protected void Page_Load(object sender, EventArgs e)
{
Response.Filter = new MinificarHTMLFiltro(Response.Filter);
}
Como ya lo dije, aquí es utilizando PageParserFilter, pero no comente que es un poco difícil (y doloroso) crear una clase que herede de PageParserFilter y haga lo que necesitamos, ya que deben construir todos los controles del árbol de controles de una pagina…
Gracias a enlace que compartió Jason Ulloa en los foros de MSDN, pude llegar hasta aquí:
Que es una implementación de PageParserFilter justamente para el objetivo de limpiar los espacios en blanco. Y podremos utilizarlo en ASP.NET Webforms y en ASP.NET MVC
Como lo implementamos, configuramos?
- Creamos nuestro PageParserFilter (o utilizamos un componente)
- Registramos en la seccion pages del web.config
<system.web>
<pages pageParserFilterType="YODA.Web.MinificarHTMLPageParserFilter">
</pages>
...
En
el ejemplo Omari Нa que lo puedes descargar
<system.web>
<pages pageParserFilterType="Omari.Web.UI.WhiteSpaceCleaner, WhiteSpaceCleanerForWebFormsAndMVC2">
</pages>
...
OPCION 5: [Idea a futuro] Componente del IIS para limpiar caracteres en blanco…minimizar
Mejorar… siempre! Para los mas experimentados… Comprimir todo en el IIS. CREAR UN COMPONENTE
Podríamos armar un componente para el IIS para que comprima el HTML resultante de cualquier pagina… ya existe? por favor háganmelo saber a través de los comentarios
Ganamos algo? Algunos inconvenientes
Comente mas arriba que hay otros lugares en nuestra app web para empezar a optimizar, porque no siempre ganamos haciendo esto de compactar la salida HTML
Problemas que podemos tener:
- Como la minificacion es automática, el documento HTML mal formado puede ocasionar una salida “no bien formada” (con errores para el renderizado en el navegador) (incluso eliminando porciones de contenido)
Por qué puede estar mal formado? porque somos nosotros simples mortales lo que escribimos parte del mismo. Todavía no es todo “autogenerado”, todavía ;)
Es decir: Si alguien se le fue “los dedos” y escribió <br> /> y al limpiar entre tags no sabremos que puede pasar.
Mas arriba comente algo sobre por ejemplo limpiar bien los saltos de linea que esta demas (y el problema de javascript)
- Hay que tener en cuenta el tiempo que involucra tener esta funcionalidad y realizarla por cada pagina, en cada peticion
Con las otras tecnicas se puede mejorar.
Tips/Recomendaciones
Esto de compactar HTML ( o CSS y JS) tiene que ir de la mano de otras técnicas para optimiza porque no es tampoco nada recomendable estar haciendo esto siempre, ya que es un punto que hay procesamiento. Por este motivo podemos ayudarnos con:
- Comprimir el contenido que se envía al cliente (típicamente con Gzip) ya la mayoría de los “mortales” utilizamos navegadores modernos que soportan recibir este tipo de contenido.
- Cachear un poco el contenido en el servidor y en el cliente cuando se pueda,
Algunos tips a tener en cuenta para optimizar aplicaciones web pueden verlo aquí:
Dejo otros enlaces mas abajo.
Síntesis
Se aprendió además de la idea de minificar el HTML, varias opciones de como modificar la salida HTML de nuestros proyectos con ASP.NET Webforms.
Ejemplo para descargar
Enlaces
- Optimizando sitio web
- PagePageFilter
Hoy me toco modificar un template de un proceso que tenemos en nuestro TFS, siempre lo modificamos online (agregar nuevos campos) pero hoy con Diego decidimos que es hora de hacerlo en un template nuevo, porque que la tarea ardua de modificar sobre el proyecto “en caliente” no era bueno repetirlo. Además el proceso ya se estandarizó en nuestro sistema de calidad.
Antes que nada… “las fuentes”!
Si quieres hablar, rezar, pensar o realizar alguna acción sobre TFS y tienes a la lengua castellana como “natural” es imposible no caer en algunos de los 1000 post de El Bruno que tiene sobre TFS (y otros temas), como se diría por aquí “el que sabe… sabe”. Los invito a visitar su blog… Así que de ahí tomo de referencia para el presente articulo, también dejo enlaces al final.
Empezamos con lo general
Para modificar todo es tocar y retocar XML, pero por por suerte tenemos las Team Foundation Server Power Tools que tiene el Process Template Editor
para VS2008 tienes TFS 2008: Power Tools (Oct/2008)
Cuando instalas tienes en Herramientas el Process Template Editor y puedes editar un work item directamente desde el servidor

O puedes abrir un Template de proceso…

Descargar/Publicar Template de Procesos
Aqui el primer paso su queremos armar un nuevo template modificando uno actual
En el menu del VS que es Team > Team Foundation Server Settings > Process Template Manager…

…o también desde el menú contextual arriba del nombre del servidor en el Explorador

Y desde alli podremos ralizar el Download de un proceso y su correspondiente Upload

Y como seguimos? Modificando los workitems necesarios…
Mas adelante publico otro ejemplo de modificar un Workitem (el que tuvimos que agregar), pero tienes este HowTo de elBruno [TFS2008] HowTo: Agregar un campo personalizado a la definición de un WorkItem
Espero que les sirva.
Enlaces
Una vez mas tuve la grata tarea de estar al frente de un curso de Control+F, al igual que el año pasado.
Terminamos a finales de Noviembre las 160 horas de formación de .NET Junior en el marco de las Becas Control+F
, en los laboratorios de la UTN FRRE
Aquí los Padawan…

El curso
En esta versión del curso de 160hs menos horas que el curso anterior del año pasado, esta vez en UTN FRRE
tenia dos cursos, unos de ellos los daba Hernán Zini (que este año no blogueo fotos todavía)
Temas:
Las Becas Control+F?
Que son las becas? es una iniciativa de capacitación en tecnologías informáticas organizada por el Ministerio de Trabajo de la Nación (Argentina)
en conjunto con CESSI
y empresas de primera línea del sector informático
Un poco mas de fotos…



… por si no se dan cuenta nos vimos desde Agosto hasta Noviembre… desde pulóveres hasta remeras 
Mas info
Muy largo el titulo! Disculpas. (Pero para el que necesita vendría bien encontrarlo por el titulo como lo queria hacer yo)
Bueno estas cosas hay que publicarlas… tal como viene a la vida y se nos presenta en nuestras pantallas
Introducción
Utilizando en un proyecto Microsoft Sync Framework (@syncfx) para utilizarlo en un componente nos descargamos en nuestro equipo de proyecto el SDK 2.1 (la version 4.0 esta en CTP desde Oct/2010 para los kamikaze), todo bien para el desarrollo en mi SO de 32bits pero cuando alguien en el equipo de desarrollo con un sistema operativo a 64bits lo quiso levantar, nos arrojaba el siguiente mensaje…
Mensaje de la excepción:
Retrieving the COM class factory for component with CLSID {031913FE-EB2A-49F2-B2BE-B996B2448CD4} failed due to the following error: 80040154 Clase no registrada (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
Mensaje
Retrieving the COM class factory for component with CLSID {C201C012-C929-4D72-B9C5-341D48630630} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
Imagen de la excepción:

Por allí en la InnerException nos tiraba una clave en la Registry dentro de WOW64 (emulación de 32bits dentro del SO de 64bits) entonces buscando algo que me diga que era
Aclaración: en la maquina de SO de 64bits se instalo el SDK 2.1 para su versión

Solución
Bueno, es obvia, si el proyecto esta compilado para x86, y los componentes no los tengo instalado los debo instalar en la de 64bit para x86, pero como no lo hicimos así y en el deploy vamos a encontrarnos con maquinas de diferentes plataformas entonces cambiamos la configuración con que se compila a que sea para “Any CPU”

Antes… (un poco de historia)
Buscando en los foros de Sync Framework dimos con muchos ejemplos de cuando no existía al versión para 64bits, pero desde la 2.0 la tenemos disponible.
En la lista de discusion de los ejemplos de MS Sync en MSDN Code Gallery encontré también en este pequeño cambio que propusieron.
Antes la única forma era emular en la maquina de 64bits, 32bits (el famoso WOW64)
Enlaces
Hace un par de meses me contactaron de Murach para realizar un comentario sobre algunos libros, que luego me enviaron …y estoy en deuda en este tema. Hoy justamente comente un par de enlaces y volví a este tema desde los foros de MSDN donde recomendamos unos de estos libros.
http://www.asp.net/community/books
http://www.asp.net/community/books/aspnet-web-forms-books
Este post lo tengo en borrador desde hace unos cuantos meses, así que en los próximos días estaré publicando brevemente que opinión merecen estos libros (aunque sea el de la tecnología que mas me agrada que es ASP.NET, EF).
Por lo pronto pueden ver la “presencia” que tienen, pero no se asusten están armados/impresos didácticamente cuando se abre en una hoja del lado izquierdo tenemos la teoría y del derecho la practica/código de la misma, particularmente me me gusto esta interesante propuesta de impresión.
Los libros:

Enlaces:
Para enviar email a través de los servidores de Google (o Google App) o de desde Hotmail/Live.com es necesario configurar puertos específicos y habilitar SSL.
Ya nos comentaban como hacerlo por código José Alarcón Aguín
Como verán era necesario habilitar por codigo SSL con la propiedad EnableSsl (del SmptClient) . “Era” la única manera/forma antes de ASP.NET 4.0...
Un pedido hacia el equipo de ASP.NET era habilitarlo desde el web.config, y lo tenemos disponible… pueden verlo en el al pedido en Microsoft Connect
Introducción: Sección mailSettings en el web.config
Desde ASP.NET 2.0, tenemos una sección de configuración mailSettings, donde podremos configurar la sección smtp
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network .... />
</smtp>
</mailSettings>
</system.net>
En la parte smtp podremos configurar como la sección network (donde tenemos por medio de atributo de configuración la posibilidad de habilitar SSL)
Configurando la seccion mailSettings podremos enviar directamente sin previa configuración de la instancia de la clase SmtpClient, … un mensaje de correo:
SmtpClient smtpClient = new SmtpClient();
try
{
smtpClient.Send(emailMsg);
}
catch (System.Net.Mail.SmtpException ex)
{
//acciones
}
Configurando… con “enableSsl” (nuevo desde ASP.NET 4.0)
Podemos incluir "EnableSSL" (que es una opción de la clase System.Net.Mail.SmtpClient) desde el archivo de configuración (sección mailSettings) y allí configurando network para el envío a través de SMTP.
Ejemplo de configuración con Google App:
Datos de servidor SMTP:
Server SMTP: smtp.gmail.com / Port: 587 / Enable SSL
User: {user}@gmail.com // {user}@tudominio.com (Google App)
Configuración:
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from=username@gmail.com >
<network enableSsl="true"
defaultCredentials="false"
clientDomain="www.tudominio.com"
host="smtp.gmail.com"
port="587"
userName="username@tudominio.com"
password="password"/>
</smtp>
</mailSettings>
Ejemplo para utilizar Live.com (nuestro Hotmail)
Datos de servidor SMTP:
Server SMTP: smtp.live.com / Port: 587 / Enable SSL
User: {user}@live.com
Configuración:
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="usuario@live.com">
<network enableSsl="true"
defaultCredentials="false"
clientDomain="www.tudominio.com"
host="smtp.live.com"
port="587"
userName="usuario@live.com"
password="password"/>
</smtp>
</mailSettings>
Puede ver mas info de los atributos de la sección
network aquí
Notas sobre “enableSsl”
…from MSDN
(…)El atributo enableSsl especifica si se usa SSL para obtener acceso a un servidor de correo SMTP.La clase System.Net.Mail.SmtpClient sólo admite la extensión de servicio SMTP para SMTP seguro sobre Seguridad de la capa de transporte como se define en RFC 3207.En este modo, la sesión de SMTP
comienza en un canal no cifrado, a continuación, el cliente ejecuta un comando STARTTLS al servidor para intercambiar para proteger la comunicación mediante SSL.Vea RFC 3207 publicada por Internet Engineering Task Force (IETF) para obtener más información.
Un método de conexión alternativo es donde una sesión de SSL se establece al frente antes de que se envíe cualquier comando de protocolo. Este método de conexión a veces se denomina SMTP/SSL y de manera predeterminada usa el puerto 465.Actualmente no se admite este método de conexión alternativo utilizando SSL.(…)
Enlaces
Hace un par de semanas estuvimos con Cristina presentando en la JUTI algunas características de Entity Framework 4.0 y ASP.NET MVC 2 con Visual Studio 2010. Aquí va el post (que lo tenia en borrador) y la presentación que nos recordó Noelia que no la publicamos aún (así que aquí esta lo que debíamos)
Esto ya nos comento Diego, que presentó con Lautaro y el invitado especial Rodrigo Eirasca (de CGE Consultores de Gestión Empresaria), el tema Certificar Calidad bajo ISO 9001:2008
Este es el 11° año de la JUTI (Jornadas Universitarias Tecnológicas sobre Informática) que se viene realizando en la UTN-FRRE (que este año esta de cincuentenario)
http://www.juti-frre.com.ar/
NOTA: Lástima que la web de la JUTI la utilicen para otros eventos, seria bueno tener un enlace “histórico” para no perder todas las versiones anteriores :(
Aquí les dejo el enlace a la presentación, y de paso la pruebo la incrustación directa :)
[Actualización 28/09/2010] FINAL
Actualización de seguridad Microsoft Security Bulletin MS10-070 – Important Asi que a descargar…. Primeramente mediante Microsoft Download Center (forma manual), o puedes (si quieres) esperar unos días y estará entre nosotros por Windows Update /Windows Server Update Service.
[Actualización 24/09/2010]
Se actualizo la solución provisoria en el aviso de seguridad Microsoft Security Advisory (2416728) para agregar un filtro mas de “protección” para este caso especifico que lee los mensajes de error de nuestra aplicación. La idea es implementar el filtro de URL para no permitir peticiones con “aspxerrorpath=” en el IIS, aquí podremos utilizar Request Filtering o URLScan (leer mas abajo la Tarea 2)
[Actualización 21/09/2010]
Doy enlace a un post de Sergio Tarrillo donde da un timeline de los últimos días y un ejemplo de aplicar la solución provisional: Reciente vulnerabilidad de ASP.NET y BlogEngine.Net
[Actualización 20/09/2010]
Doy enlace al post de Alberto Diaz donde aplica la solución provisional en SP 2010: SharePoint 2010. Vulnerabilidad 0 days de ASP.NET.
Donde en los comentarios nos da el enlace al blog de Sharepoint: Security Advisory 2416728 (Vulnerability in ASP.NET) and SharePoint.
[Actualización 19/09/2010]
Doy enlace a un post de David Salgado donde da su punto de vista (el cual comparto): El 0 day de asp.net… modo de evitarlo? y referencias
Mas de uno ya se habrá enterado pero ayer se presento en una conferencia esta vulnerabilidad (ekoparty), yo por mi parte lo encontré por un comentario de un amigo en el trabajo cuando hace dos días me envió un articulo, así que lo venia siguiendo.
Que me llevo ver los resultados de la Conferencia de Seguridad ekoparty http://www.ekoparty.org/ que presentaron el tema
La vulnerabilidad fue publicada luego de presentarse:
Y como lo comenta Scott Guthrie… , It’s important (el tiene su blog mas información). También publicó unas preguntas frecuentes
Cuando se publica la vulnerabilidad tenemos unas “soluciones de compromiso/provisionales” y también unas herramientas para que los responsables de infraestructura pueda escudriñar los sitios del IIS de un server y detectar posibles configuraciones débiles
Problema
Ayer a la tarde en la conferencia se expuso una vulnerabilidad de ASP.NET para todas las versiones de ASP.NET(desde la 1.1 a la 4.0) para todos los sistemas operativos:
“Un atacante que aprovechara esta vulnerabilidad podría ver los datos, como el estado de vista, que fue cifrado por el servidor de destino, o leer datos de archivos en el servidor de destino, como el web.config…”
Como hablamos con Lautaro, si el web.config encima tiene datos sensibles (acuérdense que se puede encriptar la cadena de conexión) estamos en graves problemas.
Mas Técnico:
Solución (provisional)
[Actualización 28/09/2010] FINAL
Ya esta la solución final (un parche de seguridad) leer aquí Microsoft Security Bulletin MS10-070 – Important
No es necesario aplicar las “soluciones provisionales” una vez aplicado la solución final
A las horas… se publicó “la contra oferta”, (para salir del paso como se diría) básicamente es:
“Habilitar los errores ASP.NET personalizado y mapear todos los códigos de error a la misma pagina de error”
Pero también utilizar una página de error “con un poco de código” (miren el enlace de Secuity Advisor) donde establece un timeout
Dos tareas a realizar “provisionalmente” para nuestra protección [Actualización 24/09/2010]
- [En la App Web] Habilitar los errores ASP.NET personalizado y mapear todos los códigos de error a la misma pagina de error (independientemente del error detectado)
- [En el Servidor IIS] Bloqueo de los request que especifican la ruta de error. Es decir no permitir “aspxerrorpath=” en el querystring
La solución final se desplegara mediante Windows Update, así que a estar atentos. Cuando vea la luz la solución final, estos “filtros de protección” ya no lo debemos aplicar.
TAREA 1: Habilitar los errores ASP.NET personalizado y mapear todos los códigos de error a la misma pagina de error
Ejemplos:
- ASP.NET 3.5 o anterior…
<location allowOverride="false">
<system.web>
<customErrors mode="On" defaultRedirect="~/error.html" />
</system.web>
</location>
- En ASP.NET 3.5 SP1 o superior (NET 4.0)
<location allowOverride="false">
<system.web>
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/ErrorPage.aspx" />
</system.web>
</location>
Como comenta Scott en su blog, también es recomendable un “delay” en la pagina de error
Ejemplo:
<script runat="server">
void Page_Load() {
byte[] delay = new byte[1];
RandomNumberGenerator prng = new RNGCryptoServiceProvider();
prng.GetBytes(delay);
Thread.Sleep((int)delay[0]);
IDisposable disposable = prng as IDisposable;
if (disposable != null) { disposable.Dispose(); }
}
</script>
TAREA 2: Bloqueo de los request que especifican la ruta de error (aspxerrorpath)
Aquí tenemos dos alternativas,
Opcion A) Request filtering
Si estamos en Windows Vista Service Pack 2, Windows Server 2008 Service Pack 2, Windows 7, Windows Server 2008 R2.
Podremos utilizar un característica del IIS 7 Request Filtering
| Windows 7 |
Windows 2008 |
Activando una característica…
|
Agregando un rol…
|
Una vez instalado debemos ir a denegar: aspxerrorpath=
Por linea de comando utilizando AppCmd
appcmd set config /section:requestfiltering /+denyQueryStringSequences.[sequence='aspxerrorpath=']
Opcion B) URLScan
Aqui utilizaremos URLScan para filtrar las peticiones en nuestros IIS (versiones 5.1/6/7)
Hay que modificar la el archivo UrlScan.ini (%windir%\system32\inetsrv\urlscan) y en la linea bajo [DenyQueryStringSequences] agregar:
aspxerrorpath=
Nos quedaría:
[DenyQueryStringSequences]
aspxerrorpath=
Herramienta (Script) para detectar las aplicaciones vulnerables
Para comenzar a fixear, ejecute la herramienta (es un script) que nos informa en un servidor ”las web con la vulnerabilidad a flor de pecho”, que los responsables de infraestructura pueden ejecutar en un server y verificar todas las web del IIS.
Espero que les sirva de ayuda o guía,… o a modo informativo.
Enlaces
Trabajando con ASP.NET MVC y Áreas, en un proyecto con múltiples Áreas, es conveniente para “enfocar el cerebro” tener en el explorador de soluciones solo los controladores y vistas del área en que estamos trabajando.
Me ayude de las extensiones de Visual Studio 2010 Productivity Power Tools, tiene una funcionalidad que es el “Navegador de Solucion” (Solution Navigator) que es una herramienta/funcionalidad All-In-One … “unión entre el explorador de soluciones, el de objetos, buscador… etc“ que nos brinda una serie de ricas funciones.
Ya nos comentaba Jersson:
Para empezar a utilizarlo…
Una de estas funciones: Crear una vista a partir de un elemento (nodo/carpeta)
En cada elemento del navegador de soluciones tenemos un botón contextual “View this as root”
Lo cual me crea un filtro en mi árbol del navegador de solución, con la raíz en el elemento que seleccionamos para “concentrarme” en el Área especifica
NOTA: Se puede hacer desde cualquier elemento ;)
Y hasta la búsqueda es contextual al “ámbito de la raíz que definimos”
Espero que les pueda ayudar como a mi.
Mas info
La semana pasada con Diego tuvimos nuevamente la grata responsabilidad de facilitar un taller sobre Scrum, el segundo de los workshop planificados en el marco del proyecto de extensión: “Formación de RRHH orientados al desarrollo de la industria del software de la región NEA” (programa La Universidad en el Medio).
Esta vez participaron docentes de la carrera de Sistemas de la UTN-FRRE
y profesionales del Polo IT Chaco
.
Presentamos el framework de trabajo pero nos llevamos como siempre un rico intercambio de experiencias.
… aquí nuevamente faltan algunos participantes por tenían que retirarse un poco antes de la “foto del recuerdo”

Mas imágenes aquí
Cuando trabajamos en ambientes web con Visual Studio 2010 tenemos a nuestra disposición los nuevos snippet de código para HTML y Javascript algo que nos puede ayudar en nuestro día a día (además de los que ya teníamos ASP.NET y sus webcontrols de versiones previas y por supuesto de ASP.NET MVC 2).
En estos días estamos en la empresa “aumentando” nuestra formación en jQuery así que saque a relucir algo que tenia en borrador desde hace un par de meses por los snippets para este framework javascript.
O sea tenemos del lado del cliente snippets:
- Snippet “out-the-box” para HTML (lo que viene con VS2010)
- Snippet “out-the-box” para Javascript (lo que viene con VS2010)
- Snippet para jQuery (no viene preinstalado, aquí hay que crear al snippet … o mejor si alguien ya lo hizo y lo compartió…
menos doloroso)
1 - Snippet para HTML
Esto lo tenemos disponible “out-the-box” (o sea preinstalado) para acortarnos camino al escribir una tag a o table… incluso para silverlight ;)
| Etiqueta/Snippet para HTML | Snippet generado |
| |
| Asi tenemos desde los “básicos” como div, table, span, etc…. | |
Como algo completo (y doloroso para escribirlo o copiarlo) como es el tag object para insertar Silverlight NOTA: En breve veremos como hacer uno para swfObject para insertar películas Flash | |
Listado Completo: Si quieres tener un listado John Sheehan (@johnsheehan) (el que armo y compartió los snippet de jQuery) tiene un “cheat sheets” de estos snippets
Inserción de un Snippet
Existen tres formas de disparar la inserción de un snippet
- La primera escribiendo el “código” del snippet (en vista del código fuente del marcado html) y luego presionando [Tab]
(No es lo mismo que los snippet de webcontrol donde hay que presionar dos veces Tab para que complete el nombre del control y luego que escriba el snippet) - La segunda mas “grafica” con el famoso menú contextual (botón derecho)
- También con las “hot-key” presionando Ctrl+K, Ctrl+X (en ese secuencia) y aparece el selector para “Insert Snippet”…
Envolver nuestro código con… en el editor HTML
También tenemos posibilidad de insertar y/o envolver nuestro código (como lo hacemos en el codebehind) pero en el editor HTML, ya nos comenta elBruno
Donde está la configuración de snippet?
Tools >> Code Snippets Manager (Ctrl+K, Ctrl+B)
Crear un Snippet, “encapsulando conocimiento”
Si quieres crear uno propio puedes escribirlo en XML (si te gusta martirizar con abrir y cerrar tags) o utilizar
En todos los casos se debe copiar el archivo miSnippet.snippet
C:\Users\{usuario}\Documents\Visual Studio 2010\Code Snippets\Visual Web Developer
Alli tienes dos carpetas My HTML Snippets y My JSScript Snippets respectivamente
NOTA: Ahora que recuerdo, tengo un post relacionado “tipo tutorial” para crear un snippet para insertar peliculas flash con swfobject, así que lo publicare en breve.
2 - Snippet para Javascript
Tenemos también “out-the-box” snippet para Javascript (lo justo y necesario)
Ejemplos:
| Etiqueta/Snippet para JS | Snippet generado |
| |
| |
3 - Snippet para jQuery
Aquí hacemos uso de jQuery Code Snippets for Visual Studio 2010 que es proyecto hosteado en CodePlex que nos agrega unos cuantos snippet. O sea o lo hacemos nosotros o utilizamos lo que alguien compartió (y nos ahorro un par de horas) esto gracias John Sheehan (@johnsheehan)
Para ayudarnos en vez del copy&paste nos da un instalador y copia en las carpetas para snippets personalizados que comente mas arriba (My HTML Snippets y My JSScript Snippets)
Entonces luego podremos ver que nos instalo unos cuentos
| Snippet para jQuery en HTML | Snippet para jQuery en JScript |
| |
NOTA: (para el quisquilloso) La versión que nos inserta para la registración de la libreria jQuery es para la 1.3.2, para tenerlo en cuenta. Tampoco creo que cambiar 1.3.2 a 1.4.2 que es la ultima sea muy difícil. Por ejemplo abriendo todos los archivos con Notepad++ y reemplazando valores.
O también te vas a la ultima revisión de código y te descargas el repositorio y reemplazas archivos.
Ejemplos:
| Etiqueta/Snippet para jQuery | Snippet generado |
| |
los CDN tanto de Google como Microsoft | |
… el $(document).ready…
| |
| | |
Listado completo de Snippet para jQuery aquí
Video de uso :
http://www.screencast.com/users/JohnSheehan/folders/Jing/media/e0787da7-5e1c-4eef-bbb9-648426204be5
[Actualización 27/08/2010]
Leyendo el blog @Jersson di con un post interesante referente a tips en la utilización de los fragmentos de código, dejo (y linkeo) el enlace
Enlaces:
Esos errores que aparecen en tu vida y vaya a saber que planetas se alinearon…
En una aplicación web con ASP.NET 3.5/VS2008 en una de las maquinas de desarrollo dio este mensaje de error el momento de debugear
Mensaje de Error:
Could not load file or assembly ‘…’ or one of its dependencies. The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
Y para “colmo de males” el mensaje directamente era por el assembly de AJAX Control Toolkit
Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies. The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
Solución efectiva y eficaz (al estilo del botón reset)
Con Diego dimos en la solución eliminando la carpeta temporal de Temporal de Archivos de ASP.NET que es donde “la magia” de la compilación dinámica genera sus archivos
Esta carpeta generalmente se encuentra aquí:
%SystemRoot%\Microsoft.NET\Framework\versionNumber\Temporary ASP.NET Files
Como estamos trabajando con ASP.NET 3.5 en core del framework es 2.0 así que la carpeta específicamente se encuentra aquí:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files
NOTA IMPORTANTE: Desarrollando en Vista/Windows 7
Justamente en la maquina donde generaba el error es un Windows 7, y si utilizamos un usuario que no es administrador local de la maquina la carpeta temporal se “redirecciona” aquí
%LocalAppData%\Temp\Temporary ASP.NET Files
Ejemplo:
c:\Users\[Usuario]\AppData\Local\Temp\Temporary ASP.NET Files
Espero que les pueda servir de ayuda o guía…
Se realizó la semana pasada el primero de los dos workshop sobre Scrum como ya había comentado, para acercarlo y poder “sentirlo” (vivenciarlo)
Esta vez participaron en su mayoría docentes de la carrera de Licenciatura en Sistemas de la UNNE – FACENA, pero también asistieron profesionales del Polo IT Corrientes y Polo IT Chaco.
Con Diego comunicamos de diferentes maneras (con dinámicas de grupo, dibujando, explicando, moviéndonos, con gráficos, y escribiendo) dejando de lado un poco “la clase magistral”
…aquí en la foto nos faltan dos personas :(
A medida que transcurrían la horas nos íbamos compenetrando e intercambiábamos tanto experiencias como compresión en los diferentes roles, artefactos y momentos que nos propone Scrum.
Y al final realizamos algo vivencial, sentir y “sufrir” lo que veníamos hablando… Practicar Scrum.
Aquí tengo que agradecer a Alan Cyment por facilitarme la dinámica del pajarraco (ya hace un par de meses para otro workshop) para realizar la simulación completa de Scrum, además con Diego hicimos unos retoques.

Aquí un par de imágenes mas…. del proceso ;)
Mas imágenes aquí
Quisiéramos agradecer a Cristina Liliam Greiner y Laly Dapozo (ambas de la UNNE) por la gestión para realizar todo esto.
Ahora se viene el segundo workshop en la UTN FRRE…
Más artículos
Página siguiente >