Trabajando con subcarpetas, CSS y Master Pages usando Page.ResolveUrl

Tengo un Master Page en el fólder raíz de mi aplicación ASP.NET.
Tengo un CSS también en el fólder raíz.
En el Master Page, mando llamar al CSS de la siguiente forma:

  1. <link href="Estilo.css" rel="stylesheet" type="text/css" />

Ahora bien, tengo una página llamada Default.aspx en el fólder raíz y otra llamada Dos.aspx en una carpeta. Las dos páginas están basadas en el Master Page. En la página Default.aspx el CSS se carga sin problemas. En la página Dos.aspx el CSS no se carga porque la aplicación no está reescribiendo la ruta del CSS, y no lo encuentra dentro de la carpeta.

Intenté esto:

  1. <link href="~/Estilo.css" rel="stylesheet" type="text/css" runat="server" />

¡Pero no funciona!

Estuve investigando y encontré la manera de hacerlo funcionar, es así:

  1. <link href='<%=Page.ResolveUrl("~/Estilo.css") %>' rel="stylesheet" type="text/css"></link>

La instrucción Page.ResolverUrl reescribe toda la ruta, sin importar en qué carpeta, sub-carpeta, sub-sub-carpeta, etc. estemos. Esto es genial ya que si un día mueves tu aplicación a un fólder virtual o a un dominio distinto, no tendrás que preocuparte por modificar estas referencias.

Lo mejor de todo es que funciona donde sea, por ejemplo:

  1. <script src='<%=Page.ResolveUrl("~/scripts/MisFunciones.js") %>' type="text/javascript"></script>

Las imágenes de las Master Pages no se ven en páginas que están en una subcarpeta

Si en un Master Page de ASP.NET pones alguna imagen de esta manera:

  1. <img src="Imagenes/MiImagen.jpg">

Todo va a funcionar bien siempre y cuando las páginas que crees a partir de tu Master Page se encuentren en la misma carpeta que el Master Page.

Intenta crear un fólder y crea una página basada en tu Master Page dentro del fólder y verás que la imagen no se ve.

Esto es porque el Master Page no modifica la ruta de tu imagen.

Para que lo haga, escribe lo siguiente en tu Master Page:

  1. <img src="~/Imagenes/MiImagen.jpg" runat="server">

La tilde, ~, sumada a la propiedad runat="server" le indican a la Master Page que reescriba las rutas de acuerdo al fólder en que se encuentra la página basada en el Master Page.

Está bien la solución anterior, pero lo mejor que puedes hacer es siempre utilizar tags de servidor. Así que para el ejemplo anterior utiliza:

  1. <asp:Image ImageUrl="~/Imagenes/MiImagen.jpg" ID="Image1" runat="server" />

Con la tilde, si tienes una página en una subcarpeta, la imagen se reescribirá así:

  1. <img src="../Imagenes/MiImagen.jpg">

Esta manera de manejar las imágenes es ideal porque si en un futuro mueves tu aplicación a cualquier otro fólder virtual, no necesitarás modificar las rutas de las imágenes.

SQL que encuentra coincidencias de un string sin usar LIKE en un .XSD de ASP.NET 2

Estoy usando .NET 2. Tengo mi archivo .XSD (Data Layer) y mi Business Logic.

El caso es que en el .XSD estoy poniendo esta consulta:

SELECT * from tabla where nombre LIKE ?

Yo quería encontrar cualquier campo que contuviera el string solicitado, es decir, si alguien buscaba “pa”, la sentencia debía regresar valores como “paco”, “palabra”, “pais”, etc. Pero con el LIKE solamente regresaba el valor si la coincidencia era exacta.

Otros intentos que hice fueron:

SELECT * from tabla where nombre LIKE '%?%'

SELECT * from tabla where nombre LIKE %?%

SELECT * from tabla where nombre LIKE %?%

Ninguno sirve porque al parecer al definir la sentencia SQL en el archivo .XSD, el signo de interrogación no puede tener ningún comodín.

Entonces busqué alguna función que pudiera ayudarme, y al final lo logré. La sentencia debe quedar así:

SELECT * from tabla where (INSTR(nombre,?) > 0)

INSTR(str,substr) devuelve la posición de la primera ocurrencia de substring en la cadena de texto str.

Así que si devuelve un número mayor a cero, significa que lo encontró.

Ahora bien, siendo más estrictos, lo que yo quería era que encontrara el principio de la palabra. Es decir, si alguien buscaba por “yo” debería encontrar “yolanda”, pero no “pelayo”. Entonces necesitaba algo que le indicara que buscara solamente al principio del campo.

Así es como lo logré:

SELECT * from tabla where nombre REGEXP CONCAT('^',?)

expr REGEXP pat realiza una búsqueda de expresiones regulares en la cadena expr usando el modelo pat.

CONCAT(cad1, cad2, ...) une cadenas de texto.

Es decir que al ejecutarse:
SELECT * from tabla where nombre REGEXP CONCAT('^','yo')

Se convierte en:
SELECT * from tabla where nombre REGEXP '^yo'

Como sabes, el símbolo ^ en expresiones regulares, significa el inicio de una palabra.

El signo ‘?’ es por si estás utilizando MySQL.

Si utilizas SQL Server, cambia el ‘?’ por ‘@Nombre’ o cualquiera que sea el nombre de tu parámetro.

Para mayor información:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

Como enviar mensajes de correo electrónico con System.Net.Mail

Para enviar mails con ASP.NET 2 necesitas utilizar System.Net.Mail.

Antes que nada, no olvides importar la librería:

  1. Imports System.Net.Mail

Para enviar el e-mail la sintaxis es la siguiente:

  1. Dim mail As New MailMessage()
  2. 'Para enviar mensaje en HTML
  3. mail.IsBodyHtml = True
  4.  
  5. 'A quien se le envia
  6. mail.To.Add("destinatario@ejemplo.com")
  7. mail.To.Add("OtroDestinatario@ejemplo.com")
  8. 'Con copia para
  9. mail.CC.Add("Copia@ejemplo.com")
  10. 'Con copia oculta
  11. mail.Bcc.Add("CopiaOculta@ejemplo.com")
  12. 'De parte de quien
  13. mail.From = New MailAddress("DeParteDeQuien@ejemplo.com", "Juan Pérez")
  14.  
  15. 'Si necesitas agregar una direccion de respuesta distinta
  16. mail.ReplyTo = New MailAddress("AQuienResponder@ejemplo.com", "Elisa Romero")
  17. 'Asunto
  18. mail.Subject = "Hola amigos"
  19. 'Cuerpo
  20. mail.Body = "<b>Hola, como están</b> todos?"
  21.  
  22. 'Por si necesitas aniadir archivos adjuntos
  23. mail.Attachments.Add(New Attachment("c:archivo1.jpg"))
  24. mail.Attachments.Add(New Attachment("c:archivo2.jpg"))
  25.  
  26. Dim smtp As New SmtpClient("127.0.0.1")  'La direccion IP del servidor SMTP
  27. 'Si deseas autenticacion usa la siguiente linea
  28. smtp.Credentials = New Net.NetworkCredential("login", "password")
  29. 'Listo, envia el mail
  30. smtp.Send(mail)

Crea tu propio validador (CustomValidator)

Para implementar tu propia lógica en un validador utiliza un CustomValidator.

En la página aspx agrega la propiedad OnServerValidate al validador y dale como valor el nombre de una función que tú mismo escribirás.

  1. <asp:customvalidator id="CustomValidator1" runat="server" CssClass="validador" Display="Dynamic" ErrorMessage="Debe seleccionar al menos un grupo" OnServerValidate="validaGrupos"></asp:customvalidator>

En el archivo aspx.vb (o en la porción de código de servidor de tu archivo aspx) implementa la función, como se muestra a continuación. Si tu lógica indica que el dato es aceptado, establece args.IsValid a true, y si no, a false.

  1. Sub validaGrupos(ByVal sender As Object, ByVal args As ServerValidateEventArgs)
  2.    Dim vacio As Boolean
  3.    vacio = True
  4.    Dim elemento As ListItem
  5.    For Each elemento In Grupos.Items
  6.       If elemento.Selected = True Then
  7.           vacio = False
  8.       End If
  9.    Next
  10.    args.IsValid = Not vacio
  11. End Sub