WordPress en IIS te da el error 404 Page not found

Este problema me ha pasado un par de veces, así que decidí poner aquí la solución para el futuro, espero que te sirva.

Instalo WordPress en IIS (Windows Server 2003) como se explica aquí, todo va bien, intento abrir mi blog mediante un navegador y me sale:

The page cannot be found

Entonces para comprobar que configuré bien el sitio web y la carpeta, pongo un archivo “hola mundo” con terminación .html. Sí abre. Pongo un archivo “hola mundo” con terminación .php. No abre.

Entro a Google y encuentro muchos artículos como este, este, y este otro, y verifico que ya hice todo correctamente. Sigue pasando lo mismo, el mismo error, The page cannot be found.

Siempre hay un punto que paso por alto, y es el siguiente. Abre tu sitio web, ve a la pestaña Home Directory, luego en la sección Application settings haz clic en el botón Configuration y luego en la pestaña Mappings encontrarás el error, tienes que dar de alta la extensión .php en Application extensions con estos parámetros:

  • Executable: “c:phpphp5isapi.dll”
    Pon las comillas, y modifica la ruta de acuerdo a tu servidor.
  • Extension: .php
  • Verbs: Limit to: GET, POST, HEAD
  • Script engine: seleccionado
  • Verify that file exists: seleccionado

, tal como se muestra en la siguiente imagen:

phpnotfound

Pasa con WordPress, pero en realidad es un problema de configuración de PHP, por lo que te puede ocurrir con cualquier otra aplicación desarrollada en ese lenguaje.

¡Suerte!

Cómo agregar el salto de lí­nea a los caracteres válidos de un FilteredTextBoxExtender

En el Ajax Control Toolkit de ASP.NET, hay un control llamado FilteredTextBoxExtender que sirve para filtrar los caracteres que se pueden ingresar en un TextBox. Esto es útil, por ejemplo, para permitir únicamente el ingreso de números si estamos capturando un código postal mexicano.

Bueno, estaba usándolo en un TextBox con la propiedad TextMode establecida en MultiLine, lo que en HTML se despliega como un textArea, una caja de texto con múltiples lí­neas.

Esta es la definición de mi caja de texto y el control de filtrado:

 <asp:TextBox 
      ID="Tags" 
      runat="server" 
      TextMode="MultiLine" 
      Width="200px" 
      Height="150px">
 </asp:TextBox>
  
 <cc1:FilteredTextBoxExtender 
      ID="Tags_FilteredTextBoxExtender" 
      runat="server" 
      Enabled="True" 
      TargetControlID="Tags" 
      ValidChars="abcdefghijklmnopqrstuvwxyz1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ">
 </cc1:FilteredTextBoxExtender> 

Como puedes ver, estoy permitiendo la entrada de letras mayúsculas, minúsculas, números y espacios. Pero como se trata de una caja de texto con míltiples lí­neas, obviamente quiero que se permita teclear saltos de lí­nea cuando el individuo presione la tecla enter o intro.

Este caso es truculento, porque no puedes hacerlo en la página aspx, lo tienes que hacer en el código de servidor, de esta forma:

Tags_FilteredTextBoxExtender.ValidChars = Tags_FilteredTextBoxExtender.ValidChars & vbCrLf

Como sabrás, vbCrLf significa un salto de lí­nea en Visual Basic, y lo que hace esa lí­nea es añadirlo a los caracteres válidos.

¡Medio truculento pero funciona!

Cómo pasar el nombre del usuario logueado como parámetro a un ObjectDataSource

Los ObjectDataSource soportan por default diferentes tipos de parámetros, como controles, cookies, Form, QueryString, Profile y Session. Sin embargo si quieres pasar como parámetro el UserName del usuario logueado no lo puedes hacer con ninguno de los tipos antes mencionados.

Para hacerlo debes utilizar el evento Selecting del ObjectDataSource.

Esto funciona así, aquí­ tenemos el ObjectDataSource:

  1. <asp:ObjectDataSource
  2.     ID="ODSEjemplo"
  3.     runat="server"
  4.     OldValuesParameterFormatString="original_{0}"
  5.     SelectMethod="GetData"
  6.     TypeName="BLLObtenerDatos">
  7. </asp:ObjectDataSource>

Fí­jate como no hemos incluido ningún parámetro. Éste lo generamos en el code-behind:

  1. Protected Sub ODSEjemplo_Selecting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceSelectingEventArgs) Handles ODSEjemplo.Selecting
  2.      e.InputParameters("MiParametro") = User.Identity.Name
  3. End Sub

Nótese que en el ejemplo, el método GetData recibe un sólo parámetro de tipo String, mismo que coincide con el tipo de User.Identity.Name

Así­ de sencillo.

Cómo leer un ConnectionString del web.config mediante código

En nuestro web.config guardamos los ConnectionStrings de nuestras bases de datos.

Ejemplo:

  1. <connectionStrings>
  2.      <add name="MiConnectionString"
  3.        connectionString="Data Source=ServidorINSTANCIASQL;Initial Catalog=MiBaseDeDatos;Persist Security Info=True;User ID=NombreDeusuario;Password=xxxxxxxxxx" providerName="System.Data.SqlClient" />
  4. </connectionStrings>

Es posible leer estos valores desde code-behind, de la siguiente forma:

  1. Dim SuperSecreto As String = System.Web.Configuration.WebConfigurationManager.ConnectionStrings("MiConnectionString").ConnectionString

Utilizar un DataPager haciendo el DataBind en Code-Behind

Como expliqué en un post anterior es posible utilizar un DataPager con un ListView de la siguiente manera:

  1. <asp:ListView ID="LVRegistros" runat="server" DataKeyNames="IdRegistro"
  2.    ItemPlaceholderID="AquiVanLosItems">
  3.     <LayoutTemplate>
  4.         <table width="100%" border="0" cellpadding="5" cellspacing="0">
  5.             <tr>
  6.                 <td class="tdDatosTitulo">Nombre
  7.                 </td>
  8.             </tr>
  9.             <asp:PlaceHolder ID="AquiVanLosItems" runat="server"></asp:PlaceHolder>
  10.             <tr>
  11.                 <td colspan="7" class="TdPie">Páginas:
  12.             <asp:DataPager ID="Pager1" runat="server" PageSize="30">
  13.                 <Fields>
  14.                     <asp:NumericPagerField ButtonCount="50" />
  15.                 </Fields>
  16.             </asp:DataPager>
  17.                 </td>
  18.             </tr>
  19.         </table>
  20.     </LayoutTemplate>
  21.     <ItemTemplate>
  22.         <tr>
  23.             <td>
  24.                 <%#Eval("IdCarpeta")%>
  25.             </td>
  26.         </tr>
  27.     </ItemTemplate>
  28.     <EmptyDataTemplate>
  29.         No existen registros.
  30.     </EmptyDataTemplate>
  31. </asp:ListView>

Ahora bien, si haces el Bind con un ObjectDataSource o algún control similar en el archivo .aspx, todo funciona perfectamente.

Sin embargo, si estás haciendo el DataBind en el código de servidor (code-behind), entonces te darás cuenta de que al hacer clic en la página número 2 (por ejemplo) del paginador, no ocurre nada, se sigue mostrando la primera página.

Esto es debido a que estás llenando el ListView en el código de servidor.

Para solucionarlo, debes colocar el siguiente procedimiento en tu archivo .aspx.vb:

  1. Protected Sub LVRegistros_PagePropertiesChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.PagePropertiesChangingEventArgs) Handles LVRegistros.PagePropertiesChanging
  2.      Pager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, False)
  3.      LVReflexiones.DataBind()
  4. End Sub

Ahora pruébalo y verás como todo funciona como debe.