[ASP.NET] Simple pero poderoso: Literal webcontrol

Justamente tenia este post en el tintero porque hace unos dias conversamos en los grupos de noticias de asp.net sobre la diferencia de webcontrol Literal y Label, y justamente hoy leí el post en Geeks.ms de Sergio Tarrillo: Diferencia entre un control Litral y un control Label (asi que los invito a leerlo con enlaces interesantes)

Asi que esta primera parte ya estaba escrita.
Si tenemos la famosa frase: «Que la fuerza te acompañe», y utilizamos los dos controles para visualizar

<asp:Label ID="lblEjemplo" runat="server" Text="Que la Fuerza te acompañe."></asp:Label>
<br />
<asp:Literal ID="ltlEjemplo" runat="server" Text="Que la Fuerza te acompañe."></asp:Literal>

Como dice Sergio en tu articulo, renderiza en esto si vemos el HTML resultante…

<span id="ctl00_contenidoCentral_lblEjemplo">Que la Fuerza te acompañe.</span>
<br />
Que la Fuerza te acompañe.
(aqui el Id del Label en el browser del cliente quedo armado: ctl00_contenidoCentral_lblEjemplo, porque esta bajo un MasterPage)
 
Como decia en ese post que hago referencia, me parece formidable tener un control sencillo pero a la vez potente; O sea, no podemos asignar estilos como el Label (con la propiedad CssClass) es limitado en ese aspecto, pero poderozo por su simpleza (es mi opinion personal) ya que es parecido a un Response.Write de  los viejos como yo que usabamos (y usamos) ASP Clásico 😉
Esto tambien trae la una consecuencia, que es que puede mostrar cualquier cosa, un script por ejemplo :O , asi que hay que tomarlo con pinzas.
Lo que nunca me gusto es cuando definen al control como «Reserva una ubicación en la página Web para mostrar texto estático.», porque reserva me da idea de esa ubicacion si no la utilizo quedara en blanco, pero bueno es algo que estoy divagando a estas horas de la noche…
Pero centremonos en una propiedad del webcontrol Literal: Mode, y sus valores posibles (PassThrough, Encode, Transform)
  • PassThrough:
    No se modifica el contenido del control.
    Ejemplo:
    <asp:Literal ID="ltlEjemplo_PassThrough" runat="server" 
                        Text="Que la <strong>Fuerza</strong> te acompañe. N° 123"
                        Mode="PassThrough"></asp:Literal> 

    Salida:

    Que la <strong>Fuerza</strong> te acompañe. N° 123
     
  • Encode:
    Se codifica el contenido a HTML
    Ejemplo:
  • <asp:Literal ID="ltlEjemplo_PassThrough" runat="server" 
                        Text="Que la <strong>Fuerza</strong> te acompañe. N° 123"
                        Mode="Encode"></asp:Literal> 

    Salida:

    Que la &lt;strong&gt;Fuerza&lt;/strong&gt; te acompa&#241;e. N&#176; 123
    
    

    Interesante modo cuando queremos presentar contenido HTML, y mostrando el codigo formateado, sin tener que recurrir a HttpUtility.HTMLEncode

 

 

  • Transform:
    Los elementos del lenguaje de marcado no compatibles se quitan del contenido del control.
    Al decir que no es compatible: si el explorador admite HTML o XHTML el comportamiento es identico al modo PassThrough
    Ejemplo:
  • <asp:Literal ID="ltlEjemplo_PassThrough" runat="server" 
                        Text="Que la <strong>Fuerza</strong> te acompañe. N° 123"
                        Mode="Transform"></asp:Literal> 
    Salida:
    Bueno como no tengo instalado un navegador wap para testar imaginemos que realiza lo que dice 😉
    Si por ejemplo la etiqueta encierra un contenido <EtiquetaNoValida>Contenido</EtiquetaNoValida>, este contenido se envia, pero la etiqueta no.
 El valor por default es Transform.
 
 
 

Enlaces

  • Label (Clase)
    Representa un control de etiqueta que muestra texto en una página Web.
  • Literal (Clase)
    Reserva una ubicación en la página Web para mostrar texto estático.
  • Literal.Mode (Propiedad)
    Obtiene o establece un valor de enumeración que especifica cómo se representa el contenido del control Literal.

String to Stream: para enviarlo como Attachment

Intentando enviar un archivo adjunto desde un string, me tope con la incertidumbre de como pasar un cadena (string) a un stream (flujo) ya que el simple casteo me generaba error

Bueno la idea primeramente era enviar un correo adjunto mediante el metodo Add de la coleccion Attachment
   

correo.Attachments.Add(New Attachment(strmMemory, "Recordatorio.htm", "text/html"))

pero necesitaba un stream (flujo) y solo tenia el contenido en cadena, y no podia , hasta que llego la

System.IO.MemoryStream
(…)La clase MemoryStream crea secuencias que utilizan como almacén de respaldo la memoria en lugar de un disco o una conexión de red. MemoryStream encapsula los datos almacenados como una matriz de bytes sin signo que se inicializa al crear un objeto MemoryStream; también se puede crear una matriz vacía. Es posible obtener acceso directamente a los datos encapsulados en la memoria. Las secuencias de memoria pueden reducir la necesidad de archivos y búferes temporales en una aplicación.(…)

El ejemplo es algo asi:

Private correo As New System.Net.Mail.MailMessage

'...varias lineas de código despues...

Dim uniEnco As New UnicodeEncoding
Dim aBytes As Byte() = uniEnco.GetBytes(_correoContenido.Cuerpo)
Dim strmMemory As New MemoryStream(aBytes)
correo.Attachments.Add(New Attachment(strmMemory, "Recordatorio.htm", "text/html"))

y luego me dedique a predicarlo jeje! posteando más a modo de recordartorio y para el que lo necesite algunas vez.
(queria que este en Geeks.ms, ya que lo habia posteado en oto lugar)

Nota:
Luego de investigar por este problema me tope con método CreateAttachmentFromString (lo dice todo el nombre no?), pero como no podía ganarme el «string to stream», decidi realizarlo de la otra forma , pero para la próxima lo uso.

 

Para los curiosos, los enlaces:

Setup Project: Insertar Crystal Report Merge Module

Hace un par de años las intalaciones de nuestros proyectos de VB6 lo haciamos (y  lo seguimos haciendo) con algunos herramientas free de instalación por ejemplo NSIS (Nullsoft Scriptable Install System), o con el famoso InstallShield (no tan free). Ya que con el setup que armaba el propio ambiente de desarrollo no nos conformaba con todas las tareas que debia realizar.
Pero esta vez iba ha utilizar un Proyecto de Instalación de Visual Studio de 2005 (incluso podemos hacer un deployment de los proyectos VB6 que aun tenemos)
Mi sorpresa, que es igual en cuando a las características de las herramientas anteriores que utilizaba: seleccionar archivos, indicar como se ubican o se van en la instalacion final o son unicamente para el proceso (ejemplo imagenes, iconos),…

[UPDATE 2008 08 08] Cambio del enlace para descargar los MergeModules. Al final del
artículo la actualización de enlaces

Antes que nada recomiendo leer un articulo que escribio Sergio Tarrillo

Deployment de Crystal Reports en Windows y Web con Visual Studio 2005 (y mas de Crystal Reports .NET)

Donde podemos encontrar un interesante manual sobre el tema. Lo que quiero mostrar aqui es como obtener el Merge Module para nuestro proyecto de instalacion.

Para crear un nuevo proyecto de Instalación

CrystalReportMergeModule000

Vamos agregando archivos, y las configuración para la instalación:

CrystalReportMergeModule003

No voy centrarme en este momento de toda la configuración que podemos realizar en un proyecto de instalación, tal vez mas adelante. Sino de los elementos necesarios para la redistribución de Crystal Report.

Pero llego el momento de colocar el paquete de redistribucion de Crystal Report .NET (para Visual Studio 2005) que seria la version 10.2 de CR (BusinessObjects.CrystalReports.NET.2.0)

Agregando Merge Modules

CrystalReportMergeModule002

Donde nos posiciona en la carpeta de los Merge Modules
        C:Program FilesCommon FilesMerge Modules
Esta carpeta esta predeterminada en nuestro sistemas para el los productos de Microsoft y de terceros coloquen alli sus archivos .msm para redistribuir sus componentes

Pero no tenia el modulo que estaba buscando que tenga que ver con el Crystal Reports for .NET Framework 2.0 (x86)

¿Y donde lo podia obtener?

[UPDATE 2008 08 08] Cambio del enlace para descargar los MergeModules. Al final del
artículo la actualización de enlaces

Es conveniente hacerlo desde la sitio oficial de Business Objects para la descarga del Crystal Reports Merge Modules for Visual Studio .NET 2005 (este enlace ya no funciona – Gracias Francisco por el
aviso)
, en cual descargamos el archivo

cr_net_2005_mergemodules_mlb_x86.zip

CrystalReportMergeModule005

y dentro del zip dentro:
CrystalReportMergeModule001
Que en un sencillo tutorial en el archivo .doc nos comenta que hagamo los mismos pasos anteriores pero antes copiemos este modulo de redistribución dentro de la carpeta que anteriormente te mencione para tenerla siempre a mano.

Bueno el costo en tamaño: Son 25Mb sumandos en mi archivo de instalación.

 

Otra alternativa

En la carpeta de
C:Program FilesMicrosoft Visual Studio 8SDKv2.0BootStrapperPackagesCrystalReports
Se encuentra el instalador para redistrbuir: CRRedist2005_x86.msi

CrystalReportMergeModule004 

http://msdn2.microsoft.com/en-us/library/fyh6k4k4(VS.80).aspx

 

 

[UPDATE 2008 08 08]

¿Y donde lo podia obtener?

Hoy (en el día de la ignauguración de los Juegos Olímpicos de Bejing) me
comenta Francisco en un post/comentario en este articulo que el enlace para la
descarga no funciona! 🙁
Cuando veo que el enlace:
   (error) http://support.businessobjects.com/communityCS/FilesAndUpdates/cr_net_2005_mergemodules_mlb_x86.zip.asp

Ahora todo parece estar en SAP 😉

Alli solamente filtrar y obtendremos los enlaces a los archivo que
necesitamos

 

 

Enlaces 

Crystal Reports Merge Modules  for Visual Studio .NET 2005
(Este enlace ya no funciona. Gracias Francisco por el aviso)

Para descargar: 
    
Business Objects Downloads for Crystal
Reports and Xcelsius
     https://www.sdn.sap.com/irj/sdn/businessobjects-downloads

Windows Installer Deployment Tasks 
http://msdn2.microsoft.com/en-us/library/ybshs20f(VS.80).aspx

How to: Create or Add Deployment Projects 
http://msdn2.microsoft.com/en-us/library/fyh6k4k4(VS.80).aspx

Setup and Deployment Projects 
http://msdn2.microsoft.com/en-us/library/wx3b589t(VS.80).aspx

How to: Add Merge Modules to a Deployment Project 
http://msdn2.microsoft.com/en-us/library/8x727h8b(VS.80).aspx

REPLACE("Windows Live Folder", "Windows Live SkyDrive"), y no morir en el intento

Estaba leyendo unos articulos del nuevo servicio «Live» (y tambien la tenia a mi querida hermana que necesita un lugar para llevar a todos lados que no sea un «reenvio a su correo», ni MI pendrive)
En geeks teniamos este artículo de Cesar con un analogía con el storage de Gmail, pero mi querida hermana necesitaba un tutorial de como utilizar y mas aun cuando no podia acceder simplemente con su cuenta passport, por esa razon quise postearla y para que le pueda servir a alguien de ayuda o guia.
Ademas de tener un menamismo para entrar sin necesidad de cambiar de país, ya que esta por ahora solamente habilitado en algunos paises este servicio.

 

NewName_SkyDrive_WindowsLiveFolder

http://folders.live.com/

 

Pero cambio de nombre y ahora lo conoceremos como Windows Live SkyDrive

LiveFolder

http://skydrive.live.com/

De donde sale el nombre? para los curiosos…

 

LiveFolder000  

Me preparo para el ingreso… y …un hermoso mensaje
         «No disponible en tu región»
o su correspondiente version
         «Not available in your region»
:S …que es esto? una «entrega a domicilio», o «pedido de pizza»?
Ya me habia sucedido algo asi con algunas funcionalidades de los servicios de Google (empezando con Gmail que para conseguir una cuenta beta habia que comprarla en ebay, suerte que tenemos amigos que nos brindaron desinteresadamente, cervceza de por medio)

Y ahora??

Queria probar (no me iba a quedar con las ganas)

Por unos minutos me teletransporte a otro lugar (unos cuantos kilometros) … vivo en Argentina, fui unos minutos a

  LiveFolder002

Donde cambiar esto??

En mi cuenta passport. Debes entrar en www.passport.com y alli modificar tu informacion de registro

 

Luego simplemente nos dirigimos a
http://folders.live.com/

y alli si…

 

image

Facil de entender para que son los tres tipos de carpetas.

Tamaño en la version beta… 500Mb (para todo el contenido de todas las carpetas)

LiveFolder003

 

Como crear carpetas

Podemos seleccionar una de las tres que vimos en la pagina principal

LiveFolder004

 

Subir Archivos

Opcion 1:
El viejo estilo o el que utilizamos al cargar un archivo en un email basado en web.

LiveFolder005

Opcion 2:
Una imagen basta…
LiveFolder006

Es un programa (para los entendidos un ActiveX, un programa que corre/se ejecuta en el explorador especificamente IE)

Y como se bloquea estas intalaciones, se necesita una «accion» por parte del usuario

LiveFolder007

LiveFolder008

LiveFolder009

LiveFolder010

que deberias permitir Instalar el Control ActiveX

 

Y con esto podemos «Arrastrar y Soltar» los archivos hacia la carpeta

 LiveFolder011

Vamos agregando archivos para luego presionar el boton «Cargar»

LiveFolder012

 

Y empieza la carga/subida de los archivos a la carpeta

LiveFolder013

Con un mensaje claro.. y preciso: «No cierres la ventana ni salgas de esta pagina»

LiveFolder014

 

Y los archivos esta en la nueva carpeta Wallpapers

LiveFolder015

 

Tenemos Vista Previa de los archivos (thumbs)
LiveFolder016

LiveFolder017

 

Y Algo que me gusto que lo lei aqui, poder incrustar la carpeta (las carpetas públicas)

LiveFolder018

LiveFolder019

Ejemplo aqui mismo mediante iframe

 

Pero no pude agregarlos a Mis Sitios de Red, ni menos abrirlo como una carpeta Web.
Esperemos que cuando no tenga mas la 4 letras («beta») podremos utilizarlo de esta forma.

 

Y mi cuenta? quedo con mi veloz viaje a otras tierras…

Para poder utilizar tuvimos que cambiar nuestro pais de origen por unos minutos, pero la sorpresa es que luego de volver a cambiar como estaba antes, a un pais de la lista de «no permitidos» :), pude seguir entrando a mis Carpetas de SkyDrive… asi que a probarlo.

Pero no me olvido de
GMail Drive
Que instala un disco virtual que hace uso de nuestro espacio en Gmail para guardar archivos, y lo vemos directamente como una disco en Mi PC
http://www.viksoe.dk/code/gmail.htm
gmail

 

Pero con un IPOD de 30GB soy autosuficiente 🙂

 

Mas info

Blogs del equipo de Live Folders
http://skydriveteam.spaces.live.com/

Un ejemplo con las carpetas del Equipo de SkyDrive
https://cid-977f793e846b3c96.skydrive.live.com/home.aspx

FreeTextBox y UpdatePanel (error renderizado)

El ambiente de trabajo sencillo, un ABM de una tabla con texto enriquecido asi que nos propusimos usar FTB (FreeTextBox), lo colocamos en dentro de un FormView y lo testeamos correctamente, hasta que se nos ocurrio la gran idea de insertar un UpdatePanel de ASP.NET Ajax, la ley de murphy se cumplia nuevamente, no renderizaba el contenido correctamente, el control se armaba pero el texto interior ni noticias.

Sintoma 1: El control lo visualizamos pero sin el contenido.
Sintoma 2: No respondia a ningun evento en sus botones o elementos (tab de modo html y modo diseño). Esto nos da un indicio que los elementos/recursos de script no estaba cargándose

Tenia algo asi…simple

       <FTB:FreeTextBox ID="ftbTramiteRequisitos" runat="server"
           Text='<%# Bind("TramiteRequisitos") %>'>
       </FTB:FreeTextBox>
FreeTextBoxYUpdatePanelErrorRender002

Probe con

       <FTB:FreeTextBox ID="ftbTramiteRequisitos" runat="server"             
            Text='<%# Bind("TramiteRequisitos") %>' 
            ButtonImagesLocation="externalFile" 
            JavaScriptLocation="externalFile" 
            ToolbarImagesLocation="externalFile"   
            SupportFolder="~/aspnet_client/FreeTextBox/"
            ScriptMode="InPage"  >
        </FTB:FreeTextBox>

y otras tanta alternativas más…Pero no queria colocar en la carpeta /aspnet_client/FreeTextBox/ los archivos necesarios (imagenes, .js, . xml) ya que para ASP.NET 2.0 todos los recursos necesarios estan embebidos en el mismo componente.

Al final googleando un poco, di con dos soluciones:

  1. Insertar dentro de un iframe, la cual no me convencia por lo compleja 😉 (aquí esta), y otra version no tan compleja aquí
  2. Registrar manualmente los scripts, que justamente alguien ya lo realizo (en los foros de FTB)

Entonces la solución:

  • El control: Lo dejo como estaba 
           <FTB:FreeTextBox ID="ftbTramiteRequisitos" runat="server"
               Text='<%# Bind("TramiteRequisitos") %>'>
           </FTB:FreeTextBox>
    Este control esta dentro de un formview, y este dentro de un UserControl
    (otras versiones aqui deberia estar todas las propiedades detalladas, pero en versiones recientes ya tiene asignadas valores predeterminados)
     
  • Y en la pagina donde utilizo el UserControl
     
    Public Overrides Sub RegisterStartupScript(ByVal key As String, ByVal script As String)
        ScriptManager.RegisterStartupScript(Me, GetType(Page), key, Replace(Replace(script, "FTB_AddEvent(window,'load',function () {", ""), "});", ""), False)
    End Sub


    Public Overloads Sub RegisterOnSubmitStatement(ByVal key As String, ByVal script As String)
        ScriptManager.RegisterOnSubmitStatement(Me, GetType(Page), key, script)
    End Sub


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Page.ClientScript.RegisterClientScriptInclude("FTBFreeTextBox", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-FreeTextBox.js"))
            Page.ClientScript.RegisterClientScriptInclude("FTBUtility", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-Utility.js"))
            Page.ClientScript.RegisterClientScriptInclude("FTBToolbarItems", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-ToolbarItems.js"))
            Page.ClientScript.RegisterClientScriptInclude("FTBPro", VirtualPathUtility.MakeRelative(Request.Path, "~/aspnet_client/FreeTextBox/FTB-Pro.js"))

        End If
    End Sub
 
      Esto tambien podrias estar y seria convenite en la MasterPage
     (la ubicacion de estos archivos es por defecto ~/aspnet_client/FreeTextBox/)
      Tendras que copiar los archivos de recursos (imagenes, js, xml) (esto viene al descargar FTB), generalmente busca en esta ubicación
              ~/aspnet_client/FreeTextBox/
       Pero la puedes cambiar pero tendras que setear estas propiedades (ademas de cambiar SupportFolder si cambias la carpeta)
     
    <FTB:FreeTextBox runat="server"
        Id="ftbTramitesRequisitos" SupportFolder="~/miCarpeta/FreeTextBoxRecursos" 
        JavaScriptLocation="ExternalFile"
        ToolbarImages="ExternalFile"
        ButtonImagesLocation="ExternalFile"  />

  Esta parte lo hice con archivos externos. Pero desde la version 3.0 viene todo esto embebido en la .dll y solo hay que agregar el handler en el web.config solo si estas trabajando con .NET 1.1

<httpHandlers>
     <add verb="GET" path="FtbWebResource.axd" type="FreeTextBoxControls.AssemblyResourceHandler, FreeTextBox" />
    </httpHandlers>