为什么在调用RoleEnvironment.GetConfigurationSettingValue("MYKEY")时我会收到SEHException异常?

39

我试图这样调用RoleEnvironment.GetConfigurationSetting("SOMEKEY")

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;
}

我的ServiceConfiguration.cscfg键看起来是这样的:

<Setting name="CHARGIFY_API_KEY" value="AbCdEfGhIjKlMnOp" />

我遇到了这个错误:

异常详细信息:System.Runtime.InteropServices.SEHException: 外部组件引发了一个异常。

[SEHException (0x80004005): 外部组件引发了一个异常。] 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() in C:\NetProjects\ChargifyDotNET\Source\Chargify.NET\ChargifyAzurePage.cs:26 Chargify.Azure._Default.Page_Load(Object sender, EventArgs e) in 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


当你在SEHException的catch块中时,Marshal.GetExceptionCode()返回什么? - Stephen Cleary
在调用Marshal.GetExceptionCode()时,返回了"-1066598274"。 - Kori
你确定你是在 Windows Azure 下运行吗?(开发环境或者真正的云端?) - user94559
我正在本地机器上运行,我猜这应该是开发环境? - Kori
具有相同的马歇尔异常代码:-532462766 - Christopher Elliott
5个回答

87

如果你尝试在非开发环境或Azure环境下访问RoleEnvironment,你会收到SEHException异常。我认为你误操作将网站运行在asp.net开发服务器下,这意味着你不在开发环境下(我已确认这会引发SEHException)。换句话说,你要么将网站项目设置为启动项目,要么右键单击它并告诉它运行。

你必须将云项目本身设置为启动项目,这将默认显示你的网站运行在端口81上。云项目是具有所有角色定义成员的项目。你可以查看浏览器的URL栏,很容易就能知道自己是否在asp.net开发服务器中运行,因为你会在某个随机端口而不是端口81上运行。

你应该通过检查 RoleEnvironment.IsAvailable 来确保你正在运行在开发环境或Azure环境中。如果返回值为true,则可以安全调用RoleEnvironment中的任何内容。如果它为false,则表示你没有在云环境中运行。


谢谢。那是一个好答案,我会验证一下 - 但我相信就是这样。 - Kori
1
关于这个问题的解决方案,我想再发表一下评论。我创建了一个库,需要在Azure和非Azure环境中运行,因此我无法直接引用RoleEnvironment。不过,我使用了反射来确定RoleEnvironment.IsAvailable()的值。 - Kori
2
一个小观察:RoleEnvironment.IsAvailable 是一个属性,而不是一个方法。 - Fernando Correia
@FernandoCorreia,你发现了我的笔误!我已经进行了编辑并进行了更正。 - David Makogon
在解决了这个问题之后(谢谢!),我遇到了一个新的问题,提示“1>无法获取设置值 1>参数名称:profileNameError:已取消”。将本地配置名称设置为“Local”而不是“Debug”或其他任何内容即可解决此问题。 - nrod

2

如果您移除 ServiceDefinition.csdef 文件中的 <Sites> 标签,这可能是一个解决方法,就像我们一样,但是您的站点将不会在云上部署到完整的 IIS。我们正在使用 SDK 的 1.7 版本。

因此,总结一下:RoleEnvironment.IsAvailable = False,并将其包含在 ServiceDefinition.csdef 中,实例计数为 1。

<Sites>
      <Site name="Blah">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Http" />
          <Binding name="Endpoint1" endpointName="Https" />
        </Bindings>
      </Site>
</Sites> 

删除<Sites>节点并部署,您可能会发现现在RoleEnvironment.IsAvailable = True

关于实际发生的情况,几乎没有任何日志 - 网站运行良好,除了通常的警告外,没有任何警告,您只有1个实例为什么不部署2个,网站正常运行。

这是一个最近的问题,我认为必须对msshrtmi.dll进行一些更改。如果RoleEnvironment不可用,它可以记录更多可能是问题的内容。


1
为了跟进这个问题,以防某些人再次遇到相同的问题,可能是你的其中一个部署在计算机仿真器中出现了卡顿。
我的情况是我有一个包含多个网站的WebRole,每个网站都绑定到不同的主机名上。例如:localhost和test.localhost。通常情况下,你会在localhost:81和test.localhost:81访问这些网站。但由于某种奇怪的原因,其中一个部署进入了一种奇怪的状态,在计算机仿真器中列出,没有Visual Studio对其进行调试,它会说“角色实例已被销毁”或类似的东西。该部署仍然在IIS中部署了网站。当我不知道这个错误的部署时,就访问了默认的URL,即test.localhost:81,它会加载旧的部署文件。在打开实际使用RoleEnvironment.GetConfigurationSettingValue方法的页面之前,(旧)站点是可以工作的,只有在那时才会出现异常。这真的很令人沮丧,因为这个虚假的部署显然没有命中任何断点,也没有停止异常,但它看起来与我正在工作的站点完全相同。
当我意识到这一点时,我在新的端口下打开了主机名,那里的页面按预期工作。一旦我从计算模拟器中删除了这个有缺陷的部署,IIS网站也被删除了,幸运的是端口现在可以按预期使用。

0

虽然很多人指出你应该使用 dev/Azure fabric 而不是 asp.net 开发服务器,但我认为值得一提的是,如果你想要使用 RoleEnvironment,在将应用程序发布到 Azure 时,需要选择正确的执行模型

现在有三种模型:

  • VM(虚拟机)
  • Web Site(网站)
  • Cloud Service(云服务)

请参考此处http://azure.microsoft.com/zh-cn/documentation/articles/fundamentals-application-models以获取更多详细信息。

特别是下面这段话:

云服务是 Azure 提供的最初执行模型,是一种显式的 PaaS 方法。尽管 PaaS 和 Web 托管之间的界限不清晰,但云服务与 Web 站点有一些重要的区别,包括以下内容:
- 与 Web 站点不同,云服务提供对应用程序虚拟机的管理访问权限。这使您可以安装应用程序需要的任意软件,这在 Web 站点中不可能。 - 因为云服务提供 Web 角色和工作角色,所以对于需要业务逻辑分离的多层应用程序来说,它比 Web 站点更好的选择。 - 云服务提供了独立的暂存和生产环境,使应用程序更新变得比 Web 站点更加顺畅。 - 与 Web 站点不同,您可以使用诸如 Azure 虚拟网络和 Azure Connect 等网络技术将本地计算机连接到云服务应用程序。 - 云服务允许您使用远程桌面直接连接到应用程序的虚拟机,这在 Web 站点中是不可能的。
您可以检查 RoleEnvironment.IsAvailable。如果它为 false,则表示您的应用程序未使用 Azure 运行时运行,这意味着 RoleEnvironment 不适用。

0

如果您确认正在运行开发环境,但仍然遇到相同的错误,请尝试将实例数减少到1。这对我有用。

不过,无法使用2个实例进行调试似乎很奇怪。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接