Forzar puerto 443 y deshabilitar puerto 80 para uso de un certificado SSL

Cuando compras un Certificado de Seguridad SSL, el sitio web que proteges se accede mediante una dirección como esta:

https://seguro.ejemplo.com

La “s” indica al navegador que se va a utilizar una conexión segura y ésta se hace por medio del puerto 443, el cual es el default para HTTPS/SSL.

Ahora bien, si no configuras nada más en tu Sitio Web y alguien teclea esta dirección:

http://seguro.ejemplo.com

notarás que todavía se puede acceder a tu aplicación, pero se está accediendo sin utilizar la seguridad que provee el certificado, lo cual es incorrecto. Lo más recomendable es indicarle a IIS que force la comunicación segura.

Para esto, abre las propiedades de tu Sitio Web en IIS y en la pestaña Directory Security, bajo el título Secure Communications oprime el botón Edit.

Ahora marca la opción Require Secure Channel (SSL) y marca también la opción Require 128-bit encryption si tu Certificado es de 128 bits.

SSL

Listo, ahora si intentas entrar a:

http://seguro.ejemplo.com

verás que el navegador te envía el siguiente error:

The page must be viewed over a secure channel
 The page you are trying to access is secured with Secure Sockets Layer (SSL).
 Please try the following:
 Type https:// at the beginning of the address you are attempting to reach and press ENTER.
 HTTP Error 403.4 - Forbidden: SSL is required to view this resource.
 Internet Information Services (IIS)

Cómo enviar un formulario en un MasterPage oprimiendo la tecla Enter

Estoy trabajando con un MasterPage, el cual tiene un campo de texto y un ImageButton para efectuar una búsqueda en el sitio web.

Tengo una página de Inicio de Sesión, la cual está basada en el MasterPage. Cuando tecleó nombre de usuario y contraseña, y oprimo Enter, en lugar de enviarse el formulario del login, se envía el formulario del MasterPage porque toma precedencia sobre el formulario del login.

Después de investigar en Google, llegué al siguiente código:

El control de Login no tiene nada de especial:

  1. <asp:Content ID="Content1" ContentPlaceHolderID="Cuerpo" Runat="Server">
  2.  
  3.     <asp:Login ID="Login1" runat="server" DisplayRememberMe="False" FailureText="Datos incorrectos, inténtelo nuevamente."
  4.        LoginButtonText="Entrar" PasswordLabelText="Contraseña:" TitleText="Inicio de sesión"
  5.        UserNameLabelText="Nombre de usuario:" LoginButtonImageUrl="~/Images/Botones/b_iniciarSesion.jpg" LoginButtonType="Image">
  6.     </asp:Login>
  7.    
  8. </asp:Content>

En el código de servidor de esa misma página, en el evento Load, coloca lo siguiente:

  1. Login1.Focus()
  2. Dim FormaPpal As HtmlForm = Master.FindControl("form1")
  3. Dim Boton As ImageButton = Login1.FindControl("LoginImageButton")
  4. If Not FormaPpal Is Nothing And Not Boton Is Nothing Then
  5.     FormaPpal.DefaultButton = Boton.UniqueID
  6. End If

Estamos estableciendo la propiedad DefaultButton del control Form en el botón del Login. Por cierto, esta propiedad también existe en el control Panel, podría ser útil en algún otro caso. Esta propiedad está diciendo que cuando se oprima la tecla Enter, se debe realizar la misma acción que cuando se hace clic en el botón indicado.

form1 es el nombre del formulario que aparece en el MasterPage

LoginImageButton no aparece en ninguna parte, pero es el nombre que se le da por default al botón de submit, ya que yo utilicé un botón de imagen.

En caso de que uses un botón regular utiliza Button en la declaración y LoginButton en el FindControl (línea 3).

Ahora bien, todo arreglado con el Login, pero cuando intento hacer una búsqueda tecleando una palabra en el campo de búsqueda (que vive en el MasterPage) y oprimo la tecla Enter, entonces se intenta enviar el formulario de inicio de sesión.

Además, en todas las otras páginas basadas en el MasterPage (y que no contienen el Login) cuando tecleo una palabra de búsqueda y oprimo Enter solamente se hace un postback, pero no se efectúa la búsqueda.

Para solucionar el problema, basta abrir el MasterPage y establecer dicha propiedad:

  1. <form id="form1" runat="server" DefaultButton="BotonIr">

BotonIr es mi botón que al ser oprimido envía a la página que realiza la búsqueda.

¡Listo! 😀

Cómo mostrar un mensaje si un DataList o Repeater está vací­o

El GridView provee una propiedad EmptyDataText en la que nosotros establecemos un texto que se desplegará si no se encuentran registros.

En un DataList no existe esta propiedad. Para mostrar el mensaje nos tenemos que valer de un Label:

  1. <asp:Label ID="Mensaje" runat="server" Text="No se encontraron registros."></asp:Label>

Después tenemos que utilizar el evento DataBinding para mostrar el mensaje y el evento ItemDataBound para ocultarlo.

El evento DataBinding ocurre primero que ItemDataBound, es por eso que al principio lo mostramos, y luego en el siguiente evento probamos si existen registros, y si no existen, lo mostramos.

La lógica queda así:

  1. Protected Sub DataList2_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataList2.DataBinding
  2.  
  3.     Mensaje.Visible = True
  4.  
  5. End Sub
  6.  
  7.  
  8. Protected Sub DataList2_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList2.ItemDataBound
  9.  
  10.     If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
  11.         Mensaje.Visible = False
  12.     End If
  13.    
  14. End Sub

Cómo obtener el tipo de un objeto con TypeOf

Estoy trabajando con un DataList y dentro de su ItemTemplate tengo lo siguiente:

  1. <asp:Image ID="Image1" runat="server" ImageUrl='<%# Funciones.DameURLImagen(Eval("Imagen")) %>' />

La función DameURLImagen debe revisar el parámetro que se le manda. Si es de tipo DBNull quiere decir que ese campo es nulo en la base de datos, así que debe mostrar una imagen genérica. Si es un String, entonces debe verificar si está vacío o no. Si lo está, se debe mostrar nuevamente la imagen genérica. Si no lo está se debe mostrar la imagen extraída de la base de datos.

Este chequeo de tipo se hace mediante TypeOf.

Aquí está nuestra función DameURLImagen:

  1. Shared Function DameURLImagen(ByVal Imagen As Object) As String
  2.     If IsDBNull(Imagen) Then
  3.         DameURLImagen = "~/Images/NoHayImagen.jpg"
  4.     Else
  5.         If TypeOf (Imagen) Is String Then
  6.             If Imagen = "" Then
  7.                 DameURLImagen = "~/Images/NoHayImagen.jpg"
  8.             Else
  9.                 DameURLImagen = "~/Images/" & Imagen
  10.             End If
  11.         Else
  12.             DameURLImagen = "~/Images/NoHayImagen.jpg"
  13.         End If
  14.     End If
  15. End Function

Cómo limpiar todos los campos de un formulario

En algunos casos uno tiene un formulario mediante el cual se dan de alta registros y se desea que la alta sea continua. Es decir, que al dar de alta un registro y oprimir un botón para guardar, la página limpie todos los campos y quede lista para volver a empezar.

Normalmente uno pensaría en restablecer todos los campos mediante código de servidor, justo después de hacer la inserción en la base de datos, algo como esto:

  1. TextBox.Text = ""
  2. DropDown1.SelectedValue = "sinseleccion"
  3. CheckBox1.Checked = False

En ocasiones no tenemos tres campos, sino 20, 30, o 40.

Para no tener que hacer el recorrido manual por cada uno de los campos, simplemente hay que hacer un redireccionamiento a la misma página. Suponiendo que nuestra página se llama Alta.aspx, haríamos esto:

  1. Response.Redirect("Alta.aspx")

Y listo, el Response.Redirect manda nuevamente a la misma página, sin hacer un postback.