martes, 15 de noviembre de 2011

El tipo no está resuelto para el miembro “X”.

El contexto

Se desarrolla un especialización para IIdentity y se establece un nuevo IPrincipal mediante GenericPrincipal con MVC3.

El síntoma

System.Runtime.Serialization.SerializationException was unhandled by user code
  Message= Type is not resolved for member 'X'.
  Source=WebDev.WebHost40

Todo bien antes de autentificarse.

image

Ingresar las credenciales

image

Horror

image

Causa poco estudiada a detalle

El problema con la serialización logré reproducirlo tanto en un sitio con Telerik (quién reportaba el error y parecía un responsable, pero nada que ver) y con un proyecto nuevo y limpio de MVC3, quién sabe por qué en mi proyecto Web antiguo (MVC2) convertido a MVC3 sí funcionaba bien.

En fin, la causa no está muy bien explicada y tiene que ver con que el Servidor Web de desarrollo de ASP.NET (WebDev.WebHost40) se ejecuta de alguna forma en la que carga el serializador por un lado (GAC) y al intentar aplicar la deserialización no encuentra el ensamblado. Por algún motivo trata de buscar el ensamblado de seguridad personalizado en otros lugares pero no el el directorio bin del propio proyecto de desarrollo.

Existen algunas soluciones alternativas recomendadas en los sitios Web

Referencia 1: Implementing a Custom Identity and IPrincipal in MVC

Referencia 2: Update on my struggles with the ASP.NET Development Server

El problema sólo sucede durante la depuración utilizando en Servidor Web de desarrollo de ASP.NET. Cuando publicas en un sitio Web de IIS no hay problemas en el encontrar el tipo.

  • Hay algunas soluciones como copiar los ensamblados relacionados a las carpetas del Net Framework correspondientes bajo Windows, pero a mí no me funcionaron.
  • Otra solución con el GAC que en ningún caso adoptaré ni lo recomiendo, además a mi tampoco me funcionó y es como volver al pasado (¡DLL HELL!).
  • Otra es personalizar completamente la serialización implementando ISerializable, es relativamente  tedioso aunque fácil, pero requiere pruebas y es absurdo en mi caso, no me gusta.

En conclusión es posible utilizar su API y publicar en los sitios de destino con IIS sin problemas.

Para poder depurar tendría que ejecutar el VS en modo administrador y cambiar el servidor Web para utilizar IIS local en las propiedades de tu proyecto.

Una solución más simple es la siguiente

Abrir en el explorador de Windows la ubicación de su servidor Web de desarrollo (WebDev.WebHost40), en mi caso:

C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0

Copiar allí, en la raíz, sus ensamblados que están relacionados y son necesarios para ejecutar su código de seguridad, sólo se requieren los ensamblados con los métodos que se cargarán durante la ejecución de su código de seguridad. No son necesarios otros ensamblados, que aunque estén relacionados en términos de referencias, no se utilicen en la comprobación.

Listo, en mi caso funciona perfecto y sigo utilizando el servidor Web de desarrollo y Visual Studio se puede ejecutar en modo de usuario, no administrador.

Gracias por todas las respuestas anteriores que me permitieron encontrar esta solución.

Saludos,

image