Azure在开发服务器上遇到问题

时间:2010-10-09 07:03:55

标签: c# silverlight rest azure

我在开发服务器上运行Azure时遇到了一些麻烦。我有一个Silverlight应用程序,我想连接到Azure,所以我从Web角色公开REST API。

这是我的服务类:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExpenseService
{
    private ExpenseDataSource expenseData = new ExpenseDataSource();

    [OperationContract]
    [WebGet(UriTemplate="expenses", ResponseFormat=WebMessageFormat.Xml)]
    public List<String> GetExpenses()
    {
        return expenseData.Select().ToList();
    }
}

ExpenseDataSource的类型初始化失败:

public class ExpenseDataSource
{
    private static CloudStorageAccount storageAccount;
    private ExpenseTableContext context;

    static ExpenseDataSource()
    {
        CloudStorageAccount.SetConfigurationSettingPublisher(
            (configName, configSettingPublisher) =>
            {
                string connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);
                configSettingPublisher(connectionString);
            }
        );

        storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

        CloudTableClient.CreateTablesFromModel(typeof(ExpenseTableContext), storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
    }
    // ...
}

错误是:

  

发现了SEHException

     

外部组件抛出了   异常。

我不确定我做错了什么。我正试图跟随这个tutorial。作者描述了需要为非Azure环境做一些不同的事情,比如NUnit测试。我是否需要在开发服务器上运行?我是否应该将此应用程序配置为使用真正的Azure存储,即使它正在我的机器上运行?

更新:如果我注释掉ExpenseDataSource构造函数并只使用虚假数据,则该服务可以正常运行。

更新2 :@Maupertuis回答我无法从静态初始化程序设置存储帐户。但是,这直接来自MS Windows Azure代码示例:

public class GuestBookEntryDataSource
{
    private static CloudStorageAccount storageAccount;
    private GuestBookDataContext context;

    static GuestBookEntryDataSource()
    {
        storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

        CloudTableClient.CreateTablesFromModel(
            typeof(GuestBookDataContext),
            storageAccount.TableEndpoint.AbsoluteUri,
            storageAccount.Credentials);
    }
    // ...
 }

这可能有用吗?

2 个答案:

答案 0 :(得分:1)

正如我之前所说(aaarg .. SO停机),您无法从静态构造函数中初始化您的Cloud Apps,因为静态构造函数将在类型初始化时调用。加载程序集时,但第一次使用类型时,不会发生类型初始化。

你应该使用create一个派生自RoleEntryPoint类的类。它将在角色启动时调用OnStart方法。

以下是一个示例:

public class WebRole: RoleEntryPoint
    {
        public override bool OnStart()
            {
            #region Setup CloudStorageAccount Configuration Setting Publisher

            // This code sets up a handler to update CloudStorageAccount instances when their corresponding
            // configuration settings change in the service configuration file.
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                // Provide the configSetter with the initial value
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (sender, arg) =>
                {
                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                        .Any((change) => (change.ConfigurationSettingName == configName)))
                    {
                        // The corresponding configuration setting has changed, propagate the value
                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                        {
                            // In this case, the change to the storage account credentials in the
                            // service configuration is significant enough that the role needs to be
                            // recycled in order to use the latest settings. (for example, the 
                                // endpoint has changed)
                            RoleEnvironment.RequestRecycle();
                        }
                    }
                };
            });
            #endregion

            return base.OnStart();
        }
    }

答案 1 :(得分:0)

您不应该从静态构造函数中调用SetConfigurationSettingPublisher。它不能保证完全运行,如果它运行,则无法保证何时运行。

如果确实如此,可以保证它将在Type初始化时执行。这是在第一次使用您的类ExpenseDataSource之前。如果不在应用程序中使用它,则也不会执行静态构造函数。由于必须在第一个请求之前调用SetConfigurationSettingPublisher(如果我记得很清楚),您将理解静态构造函数不是真正的方法。

您应该创建一个派生自RoleEntryPoint的类,Azure平台在启动时始终会调用其OnStart覆盖:

public class WebRole: RoleEntryPoint
    {
        public override bool OnStart()
        {
            #region Setup CloudStorageAccount Configuration Setting Publisher

            // This code sets up a handler to update CloudStorageAccount instances when their corresponding
            // configuration settings change in the service configuration file.
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                // Provide the configSetter with the initial value
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (sender, arg) =>
                {
                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                        .Any((change) => (change.ConfigurationSettingName == configName)))
                    {
                        // The corresponding configuration setting has changed, propagate the value
                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                        {
                            // In this case, the change to the storage account credentials in the
                            // service configuration is significant enough that the role needs to be
                            // recycled in order to use the latest settings. (for example, the 
                            // endpoint has changed)
                            RoleEnvironment.RequestRecycle();
                        }
                    }
                };
            });
            #endregion

            return base.OnStart();
        }
    }

这是一个例子,您可以将应用程序所需的初始化代码放在此处。