2010-10-09 82 views
2

我在开发服务器上进行Azure工作时遇到了一些麻烦。我有一个我想连接到Azure的Silverlight应用程序,因此我从Web角色公开了一个REST API。开发服务器上的Azure问题

这里是我的服务类:

[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被抓获

外部合作mponent已抛出一个 异常。

我不知道我在做什么错。我正在尝试跟随此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); 
    } 
    // ... 
} 

难道这能工作吗?

回答

1

正如前面所述(aaarg .. SO outage),您无法从静态构造函数中初始化您的Cloud Apps,因为将在类型初始化时调用静态构造函数。装入程序集时不会发生类型初始化,但是第一次使用类型时。

您应该使用创建一个从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(); 
     } 
    } 
+0

是的,SO停电是一个巨大的痛苦。谢谢你的回答,我会试试这个。我认为这样做的原因可以从我从MSFT下载的Windows Azure培训套件(上面贴出)中找到。奇。 – 2010-10-09 16:14:36

+0

我把'SetConfigurationSettingPublisher'调用放在'OnStart()'中,但它永远不会被调用。我在那里没有被击中的断点。我认为'OnStart()'总是跑? – 2010-10-09 16:43:02

+1

WebRole类是公开的吗?它是否继承自RoleEntryPoint?它是您的应用唯一的RoleEntryPoint类吗? – Eilistraee 2010-10-11 10:44:32

0

你不应该从静态构造函数中调用SetConfigurationSettingPublisher。它不保证运行,如果运行,也不保证运行的时间。

如果实际上有保证它会在类型初始化时执行。在第一次使用类ExpenseDataSource之前。如果你不在应用程序中使用它,静态构造函数也不会被执行。由于必须在第一个请求之前调用SetConfigurationSettingPublisher(如果我没记错的话),你会明白静态构造函数并不是真正的方法。

,当它启动时,你应该创建一个类从RoleEntryPoint,它的OnStart倍率总是由Azure平台被称为派生:

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

这是一个例子,你可以把这里所要求的任何初始化代码你应用。