Sys.Debug.isDebug es nulo o no es un objeto

Si cuando intentas ver tu aplicación de Ajax en Internet Explorer te marca un error de JavaScript que dice:

'Sys.Debug.isDebug' es nulo o no es un objeto

En inglés:

'Sys.Debug.isDebug' is null or not an object

lo más probable es que no has instalado las últimas extensiones. Haz lo siguiente:

  1. Desinstala las Extensiones de Ajax
  2. Reinicia el IIS
  3. Descarga e instala las Extensiones de Ajax más nuevas de www.asp.net
  4. Reinicia el IIS

Todo debe funcionar después de estos pasos.

Si no es así, quizás debas revisar tu código ya que han habido algunos cambios a lo largo de la historia de Ajax.

Redirige al usuario a diferentes páginas de acuerdo a su Rol

Esta información aplica para ASP.NET 2 con autenticación mediante MembershipProvider y RoleProvider.

Si tienes dos o más distintos Roles, y quieres que cuando el usuario inicie sesión, se verifique a qué Rol pertenece, y de acuerdo a esto se le envié a una página distinta, haz lo siguiente:

Tu página de login no necesita nada especial, simplemente un control para loguearse:

  1. <asp:Login ID="Acceso" runat="server">
  2. </asp:Login>

En el código de servidor de tu página, tienes que usar el método LoggedIn del control Login, hazlo así:

  1. Protected Sub Acceso_LoggedIn(ByVal sender As Object, ByVal e As System.EventArgs) Handles Acceso.LoggedIn
  2.         If Roles.IsUserInRole(Acceso.UserName, "admin") Then
  3.             Response.Redirect("~/Admin/Default.aspx")
  4.         Else
  5.             If Roles.IsUserInRole(Acceso.UserName, "capturista") Then
  6.                 Response.Redirect("~/Capturista/Default.aspx")
  7.             End If
  8.         End If
  9.     End Sub

Cómo usar autenticación por Roles y Usuarios en ASP.NET 2

La autenticación de ASP.NET 2 nos permite tener una estructura de Roles y Usuarios. Puedes tener algo así:

Administradores
jlopez
pperez
fgonzalez

Capturista
pperez
ymartinez

Nota que en el ejemplo anterior pperez aparece en ambos grupos. Esto es posible y es correcto. En el ejemplo, pperez funge como administrador y como capturista a la vez.

Ahora supongamos que tengo una carpeta para administradores y otra carpeta para capturistas en el fólder raíz de mi aplicación:

Fólders

Lo que voy a hacer para poder autenticar por roles es abrir el archivo web.config y colocar la siguiente porción de código:

  1. <location path="admin">
  2.   <system.web>
  3.     <authorization>
  4.       <allow roles="admin"/>
  5.       <deny users="*"/>
  6.     </authorization>
  7.   </system.web>
  8. </location>
  9.  
  10. <location path="capturista">
  11.   <system.web>
  12.     <authorization>
  13.       <allow roles="admin,capturista"/>
  14.       <deny users="*"/>
  15.     </authorization>
  16.   </system.web>
  17. </location>

justamente bajo la sección configuration.

Nota que estamos dejando entrar a ciertos roles usando la entrada allow y estamos denegando a todos (con el asterisco) usando deny. El orden es importante, si lo inviertes, primero se denegaría a todos los usuarios, y después se intentaría permitir el acceso a los roles, lo cual significaría que no estarías dejando entrar a nadie.

NOTA:
Para que esto funcione correctamente, debes estar utilizando un MembershipProvider y un RoleProvider. Si estás conectando con SQL Server te será fácil encontrar información en Google. Si por casualidad estás intentando conectarte con MySQL, lee este post.

Más información:
Authentication y Authorization
Autorizando Usuarios y Roles

MembershipProvider y RoleProvider para MySQL para ASP.NET 2

Microsoft provee un MembershipProvider y RoleProvider en el Framework de ASP.NET, pero solamente funcionan para SQL Server.

Afortunadamente Rakotomalala Andriniaina se dió a la tarea de escribir ambos Providers para que se conecten a MySQL, y así poder usar toda la funcionalidad de Autenticación de ASP.NET 2 con esta base de datos.

Entra a:

http://makoto.madmedia.ca/2007/03/mysql-membership-and-role-provider-for.html

y descarga el archivo Release.zip.

Copia el fólder bin en la raíz de tu aplicación.

Crea tu base de datos en MySQL, y genera las tablas utilizando el archivo create_tables.sql. Deberán haberse creado tres tablas: roles, users y usersinroles.

Nota:
También necesitarás el Connector/Net 1.0. Solamente descárgalo e instálalo en el servidor donde corre la aplicación.

Abre el archivo web.config que viene en la liga anterior y copia las líneas que ahí aparecen al web.config de tu aplicación.

Recuerda modificar los valores del connectionString por los tuyos.

También modifica el valor YOURAPPNAME por el nombre de tu aplicación (el que tú eligas). Aparece dos veces.

Si quieres puedes modificar el valor de encryptionKey por un número hexadecimal de tu elección, pero si no sabes lo que estás haciendo mejor déjalo así.

Es muy importante que modifiques el valor de loginUrl en el nodo forms. Coloca la ruta de tu página de Login. Recuerda que la tilde ~ significa la raíz de tu aplicación.

Ahora ya está todo listo. Ya puedes usar los componentes de Autenticación de ASP.NET 2 (Login, LoginView, PasswordRecovery, LoginStatus, LoginName, CreateUserWizard, ChangePassword) con MySQL.

Para probar que todo está funcionando correctamente, crea tu página de Login y coloca un control CreateUserWizard básico:

  1. <asp:CreateUserWizard ID="CreateUserWizard1" runat="server">
  2.     <WizardSteps>
  3.         <asp:CreateUserWizardStep runat="server">
  4.         </asp:CreateUserWizardStep>
  5.         <asp:CompleteWizardStep runat="server">
  6.         </asp:CompleteWizardStep>
  7.     </WizardSteps>
  8. </asp:CreateUserWizard>

Si necesitas utilizar autenticación por roles, lee este post.

Actualización

Todo funcionó perfectamente como lo describí en este post en mi servidor de pruebas, pero en mi servidor de producción, el cual tiene exactamente la misma configuración, me marcaba este error:

Parser Error Message: Could not load type 'Andri.Web.MySqlRoleProvider'.

Revisé todas las configuraciones y no encontré nada, todo estaba bien. Entonces procedí a hacer esto de otra manera porque ya tenía otro proyecto trabajando igual, así que esta es una solución comprobada:

No muevas nada de la configuración del MembershipProvider que hayas hecho en el web.config, eso sigue estando bien.

Del fólder bin elimina la librería MySQL Membership and Role Providers.dll. No elimines MySql.Data.Dll.

Ahora bien, como ya no tenemos la librería usaremos los archivos fuente que Rakotomalala escribió en C#. Si estás haciendo toda tu aplicación en ese lenguaje, simplemente coloca los archivos MySQLMembershipProvider.cs y MySQLRoleProvider.cs en tu carpeta App_Code y listo, ahora sí funcionará todo como debe ser.

Pero si estás usando VB:

Si estás haciendo tu aplicación en VB entonces no puedes simplemente colocar los archivos mencionados anteriormente en tu carpeta App_Code porque si tienes dos lenguajes tienes que colocarlos en carpetas distintas. Crea dos carpetas, una para cada lenguaje, de tal forma que tengas esto:

Dos lenguajes

Ahora bien, coloca dentro de VBCode todos tus archivos fuente VB y dentro de CSCode todos tus archivos fuente C#.

No has terminado, porque le tienes que indicar a la aplicación lo que estás haciendo. Abre tu archivo web.config y dentro del nodo compilation coloca lo siguiente:

  1. <codeSubDirectories>
  2.   <add directoryName="VBCode" />
  3.   <add directoryName="CSCode" />
  4. </codeSubDirectories>

Ahora sí, has terminado, todo debe funcionar correctamente.

Por si acaso, aquí están los archivos:

Utiliza String.Format para establecer el valor de ImageUrl de un tag asp:Image dentro de un DataList

Me estuve peleando un rato con esto, hasta que encontré la solución.

Tengo un DataList, y dentro de él aparecen imágenes cuya ruta se forma a partir de un valor devuelto por la base de datos.

Mi primera idea fue tratar de unir la ruta con el Eval, de esta forma:

  1. <asp:Image ImageUrl='~/postales/thumbs/<%# Eval("archivoThumbnail") %>' BorderStyle="None" CssClass="bordeImagenGris" Height="80" Width="80" ID="Image1" runat="server" />

Pero dado que el Eval aparece dentro de las comillas simples de ImageUrl, el valor es pasado tal cual, así que la imagen nunca es encontrada.

Para resolverlo, tienes que usar la función String.Format, de esta manera:

  1. <asp:Image ImageUrl=<%# String.Format("~/postales/thumbs/{0}",Eval("archivoThumbnail"))%> BorderStyle="None" CssClass="bordeImagenGris" Height="80" Width="80" ID="Image1" runat="server" />

Sobre String.Format

La función String.Format es un concatenador (valga el término) de cadenas de texto. Toma n parámetros. Cada parámetro se define por un número encerrado entre llaves ({ y }), y a cada parámetro existente debes darle un valor.

Como siempre, es más fácil entenderlo con un ejemplo:

  1. String.Format("Roger {0} es el mejor {1} del {2}", "Federer", "tenista", "mundo")
  2. 'Esto regresará el siguiente texto:
  3. 'Roger Federer es el mejor tenista del mundo