Проблема с Azure на сервере разработки - PullRequest
2 голосов
/ 09 октября 2010

У меня проблемы с работой Azure на сервере разработчика.У меня есть приложение Silverlight, которое я хотел бы подключить к Azure, поэтому я представляю 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 был обнаружен

Внешний компонент выдал исключение.

Я не уверен, что я делаю неправильно.Я пытаюсь следовать этому уроку .Автор описывает необходимость сделать что-то другое для сред, отличных от Azure, таких как тесты NUnit.Нужно ли что-то делать для запуска на сервере dev?Должен ли я просто настроить это приложение для использования реального хранилища 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 ]

1 голос
/ 09 октября 2010

Как я уже говорил ранее (aaarg .. SO отключение), вы не можете инициализировать ваши облачные приложения из статического конструктора, так как статический конструктор будет вызываться при инициализации типа.Инициализация типа не происходит при загрузке сборки, но когда ваш тип используется впервые.

, вы должны использовать создать класс, производный от класса RoleEntryPoint.метод OnStart будет вызываться при запуске Role.

Вот пример:

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 голосов
/ 09 октября 2010

Вы не должны вызывать 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();
        }
    }

Это пример, вы можете поместить здесь любой код инициализации, требуемый вашим приложением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...