Default Membership y SQLExpress UserInstance
Estos días estoy pegándome con Silverlight RIA Services, y resulta que todas las demos y tutoriales que he encontrado usan Membership, pero en vez de indicar la cadena de conexión en el Web.Config, se usa la configuración por defecto.
Esta configuración utiliza una característica de SQLEXPRESS que permite “attachar” dinámicamente la base de datos en base a un fichero mdf y se denomina User Instance.
Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnetdb.mdf;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True
Bueno, pues resulta que por motivos del guión tuve que actualizar mi instancia de SQLExpress a una instancia superior (Standard o DataCenter, para el caso da igual). Y mira por donde que en estás ediciones (SKUs) no se soporta esta funcionalidad, el mensaje de error lo deja bastante claro:
The user instance login flag is not supported on this version of SQL Server. The connection will be closed.
Esto no deja de ser un gran engorro, porque cada vez que quiero instalar un ejemplo tengo que reconfigurar todos los parámetros de membership.
Para solucionar el problema, lo primero que hice fue consultar con ialonso, para ver si puedo usar algún truqui para habilitar esta funcionalidad en mi edición datacenter. La respuesta fue curiosa: “Tienes 3 opciones”:
- Instalar SQLEXPRESS que implicaria desinstalar mi namedinstance SQLEXPRESS, y reinstalar de nuevo)
- Usar NON-GOLDENBITS (vaya término) y pasar un TraceFlag. Pero entiendo que también seria necesario reinstalar
- Meter un breakpoint con WinDbg en sqlservr!LCheckUserInstanceFlagUsage y cambiar el valor de retorno <—Esto es lo más friki, y aunque estoy seguro que funcionaria, tendria que estar con el depurador abierto cada vez me conecto a SQL… no way
Como ninguna de las tres opciones me convence, empecé a buscar por otro lado, concretamente el fichero en que se define la configuración por defecto, tiene que ser el machine.config o el web.config general. Pero en vez de empezar a buscar a lo loco, utilice la siguiente técnica.
Cree un endpoint que leia la configuración del Membership actual, aunque no se haya indicado nada en el Web.Config (notese el uso de reflection para acceder al campo en donde se almacena la cadena de conexión):
var cs = Membership.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Membership.Provider);
Una vez comprobado que el valor era una cadena de conexión definia la opción UserInstance, los siguiente era buscar el fichero que contenia dicha cadena.
Gracias al depurador histórico, IntelliTrace, y después de habilitar el log de accesos a ficheros, pude obtener los ficheros que se estaban leyendo:
Y voila, la cadena de conexión se encontraba en el machine.config.
Cambiado y problema solucionado
PD: como extra, os dejo el tipo información que se puede obtener con este depurador sin necesidad de modificar la aplicación.