¿Por qué recibo SEHException cuando llamo a RoleEnvironment.GetConfigurationSettingValue (“MYKEY”)?

Estoy intentando llamar a RoleEnvironment.GetConfigurationSetting("SOMEKEY") así:

 public partial class AzureBasePage : System.Web.UI.Page { protected ChargifyConnect Chargify { get { if (this._chargify == null) { this._chargify = new ChargifyConnect(); this._chargify.apiKey = RoleEnvironment.GetConfigurationSettingValue("CHARGIFY_API_KEY"); } return this._chargify; } } private ChargifyConnect _chargify = null; } 

Mi clave ServiceConfiguration.cscfg tiene este aspecto:

  

Y obtengo este error:

Detalles de la excepción: System.Runtime.InteropServices.SEHException: componente externo ha lanzado una excepción.

[SEHException (0x80004005): el componente externo ha lanzado una excepción.] RoleEnvironmentGetConfigurationSettingValueW (UInt16 *, UInt16 *, UInt32, UInt32 *) +0 Microsoft.WindowsAzure.ServiceRuntime.Internal.InteropRoleManager.GetConfigurationSetting (String name, String & ret) +92 Microsoft .WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue (String configurationSettingName) +67 ChargifyNET.ChargifyAzurePage.get_Chargify () en C: \ NetProjects \ ChargifyDotNET \ Source \ Chargify.NET \ ChargifyAzurePage.cs: 26 Chargify.Azure._Default.Page_Load (Object remitente , EventArgs e) en C: \ NetProjects \ ChargifyDotNET \ Source \ Chargify.Azure \ Default.aspx.vb: 8 System.Web.UI.Control.OnLoad (EventArgs e) +99 System.Web.UI.Control.LoadRecursive ( ) +50 System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Obtendrá SEHException si intenta acceder a RoleEnvironment si no se está ejecutando en el tejido dev o en Azure Fabric. Creo que inadvertidamente está ejecutando su sitio web en el servidor de desarrollo asp.net, lo que significa que no está en el tejido de desarrollo (he confirmado que esto arrojará una SEHException). En otras palabras, ha configurado el proyecto de su sitio web como el proyecto de inicio o lo ha hecho clic derecho y le indicó que se ejecute.

Debe establecer el proyecto de la nube como el proyecto de inicio, que luego mostrará su sitio web ejecutándose en el puerto 81 de manera predeterminada. El proyecto de la nube es el proyecto que tiene, como sus miembros, todas las definiciones de su función. Puede ver la barra de direcciones URL de su navegador y saber fácilmente si se está ejecutando en el servidor de desarrollo asp.net, porque estará en un número de puerto aleatorio en lugar del puerto 81.

Debe asegurarse de que se está ejecutando en el enttwigdo dev o en el elemento Azure marcando RoleEnvironment.IsAvailable . Si eso es cierto, puedes llamar a cualquier cosa en RoleEnvironment. Si es falso, no se está ejecutando dentro del tejido.

Eliminar la etiqueta en el archivo ServiceDefinition.csdef podría ser una solución para usted, como lo fue para nosotros, pero luego su sitio no se implementará en Full IIS en la nube. Estamos usando 1.7 del SDK.

En resumen: RoleEnvironment.IsAvailable = False con esto incluido en ServiceDefinition.csdef con un recuento de instancias de 1 que podría agregar.

         

Elimine el nodo e impleméntelo y puede encontrar que ahora RoleEnvironment.IsAvailable = True .

Hay muy pocos registros sobre lo que realmente está sucediendo: el sitio web está funcionando bien, no hay advertencias, excepto la habitual, solo tiene 1 instancia, por qué no implementar 2 y el sitio está funcionando correctamente.

Este es un problema reciente y creo que debe haber algunos cambios realizados en ese msshrtmi.dll. Podría registrar un poco más de lo que en realidad podría ser el problema si RoleEnvironment no está disponible.

Para dar seguimiento a eso, en caso de que alguien vuelva a encontrarse con el mismo problema, también podría darse el caso de que, por alguna razón, una de sus implementaciones se quedara atascada en el emulador de cómputo.

Lo que me sucedió fue que tenía un webrole que contenía varios sitios web, cada uno vinculado a un nombre de host diferente. Diga: localhost y test.localhost. Normalmente, tendría acceso a estos en localhost: 81 y test.localhost: 81. Sin embargo, por alguna extraña razón, una implementación llegó a un estado extraño donde se enumeraría en el emulador de cómputo, sin que Visual Studio lo depurara, diría “Instancia de rol destruida” o algo similar. Esta implementación aún tenía el sitios web desplegados en IIS. Entonces, sin saber sobre esta implementación defectuosa, accedí a las direcciones URL predeterminadas, es decir. test.localhost: 81 que cargaría los archivos de implementación anteriores. El (viejo) sitio funcionó hasta que abrí una página que realmente usaba el método RoleEnvironment.GetConfigurationSettingValue , y solo entonces obtuve esa excepción. Fue realmente frustrante, ya que este despliegue de boggus no llegó a ningún punto de ruptura ni se rompió en las excepciones, sin embargo, se veía exactamente como el sitio en el que he estado trabajando.

Cuando me di cuenta de esto, abrí los nombres de host bajo el nuevo puerto y allí las páginas funcionaban como se esperaba. Una vez que eliminé esta implementación defectuosa del emulador de cómputo, los sitios web de IIS también se eliminaron y, afortunadamente, los puertos ahora están disponibles para su uso como se esperaba.

Si obtiene el mismo error después de asegurarse de que está ejecutando el tejido dev, intente reducir el recuento de instancias a uno. Eso lo solucionó para mí.

Aún así, parece raro que no pueda depurar con 2 instancias.

Aunque muchos señalan que debe ejecutar con dev / Azure Fabric en lugar del servidor de desarrollo asp.net, creo que vale la pena mencionar que debe elegir el modelo de ejecución correcto cuando publique su aplicación en Azure si desea usar RoleEnvironment. .

Hay 3 modelos a partir de ahora:

  • VM
  • Sitio web
  • Servicio de almacenamiento en la nube

Consulte aquí: http://azure.microsoft.com/en-us/documentation/articles/fundamentals-application-models para obtener más información.

Y especialmente el siguiente párrafo:

Cloud Services, que fue el modelo de ejecución inicial proporcionado por Azure, es un enfoque explícitamente PaaS. Si bien la línea entre PaaS y el alojamiento web es borrosa, los servicios en la nube difieren en algunos aspectos importantes de los sitios web, incluidos los siguientes:

  • A diferencia de los sitios web, los servicios en la nube le brindan acceso administrativo a las máquinas virtuales de su aplicación. Esto le permite instalar el software arbitrario que su aplicación necesita, algo que no es posible con los sitios web.
  • Debido a que los servicios en la nube ofrecen tanto roles web como roles de trabajador, es una mejor opción que los sitios web para aplicaciones de varios niveles que necesitan máquinas virtuales separadas para su lógica comercial.
  • Los servicios en la nube proporcionan entornos separados de producción y producción, lo que hace que las actualizaciones de las aplicaciones sean más fluidas que los sitios web.
  • A diferencia de los sitios web, puede usar tecnologías de red como Azure Virtual Network y Azure Connect para conectar las computadoras locales a las aplicaciones de Cloud Services.
  • Los servicios en la nube le permiten usar el escritorio remoto para conectarse directamente a las máquinas virtuales de una aplicación, algo que no es posible con los sitios web.

Puede verificar RoleEnvironment.IsAvailable . Si es falso, su aplicación no se ejecuta con el tiempo de ejecución de Azure, lo que significa que RoleEnvironment no es aplicable.