Je désire partager avec vous quelques constats lors d’une migration ou développement sur la plateforme Azure. (Ce post fera l’objet de plusieurs mises à jours)
1. Les DateTime
Si l’application s’appuie fortement sur les dates (par exemple l’activation d’une fonctionnalité pendant X minutes), il est fortement préférable d’utiliser DateTime.UtcNow plutôt que DateTime.Now. D’une façon plus générale, préférez l’utilisation du Coordinated Universal Time aussi bien dans l’application que dans vos procédures stockées.
Pourquoi?
La raison est très simple, le jour où vous n’aurez plus la maitrise sur le déploiement géographique de vos applications (typiquement Azure), vous n’aurez plus la main sur le localtime du serveur. Il se trouve qu’Azure s’appuie sur l’UTC dans tous ses DataCenters.
2. Le Parsing des décimaux
L’éternel casse-tête, virgule ou point? Le système anglo-saxon utilise un point alors que tous les autres systèmes utiliseraient la virgule comme séparateur décimal. Pour ne plus avoir de soucis, définissez d’ores et déjà le système que vous allez utiliser. Dans vos conversions, spécifiez la culture info!
Pourquoi?
Par exemple :
Code Snippet
- double.Parse("7,3", CultureInfo.GetCultureInfo("fr-FR"));
Renverra 7.3 dans tous les systèmes quelque soit la culture du serveur alors que
renverra 73 dans les systèmes anglo-saxons et 7.3 dans les autres systèmes!
Or dans Azure on n’est sûr de rien… A priori c’est un système anglo-saxon donc attention!
3. PathTooLongException
Un projet en cours de migration utilise Entreprise Library et les noms d’assembly sont juste trop long, du coup lors de tests en local, je me confronte à un PathTooLongException. Le projet se déployait dans un répertoire du type :
C:\Users\Ronny KWON\AppData\Local\dftmp\s0\deployment(168)
Il existe une astuce pour pouvoir déployer dans un répertoire de notre choix, il suffit d’ajouter la variable système “_CSRUN_STATE_DIRECTORY”, spécifier un répertoire, fermer visual studio et la dev fabric et relancez le tout.
4. La configuration
Lors d’une migration, on sera souvent confronté au problème de configuration puisqu’à l’initial, toutes les configurations se retrouvent dans le web.config. Cela signifie que si on souhaite changer un appsetting, il faut redéployer la solution! Or il est possible d’extraire ces appsettings et les renseigner dans le ServiceConfiguration et le ServiceDefinition. Seul hic : la syntaxe est différente
un appsetting c’est :
Code Snippet
- <add key="SessionMax" value="60"/>
une configuration Azure ça sera plutôt :
| ServiceDefinition | ServiceConfiguration |
Code Snippet - <Setting name="SessionMax"/>
| Code Snippet - <Setting name="SessionMax" value="60"/>
|
Un travail long et douloureux si les configurations sont nombreuses!
Je vous propose un draft de code qui permet de transformer des appsettings en configuration pour azure (definition + configuration)
Code Snippet
- // on récupère les appsettings
- string config = AppConfigurationTextBox.Text;
-
- if (!String.IsNullOrEmpty(config))
- {
- string serviceConfiguration = Regex.Replace(config, "add key", "Setting name");
- string serviceDefinition = Regex.Replace(serviceConfiguration, "value[:b]*=[:b]*\"(.*)\"", "");
-
- ServiceDefinitionTextBox.Text = serviceDefinition;
- ServiceConfigurationTextBox.Text = serviceConfiguration;
- }
5. Gérer le double environnement d’exécution de vos applications (Azure & On-Premises)
Garder la possibilité de déployer l’application aussi bien sur Azure que dans un serveur web s’est s’assurer une certaine indépendance vis à vis de la plateforme Azure, une variable permet de détecter l’environnement d’exécution d’Azure :
Code Snippet
- RoleEnvironment.IsAvailable
Typiquement, vous pourrez combiner cette variable avec la lecture de configuration par exemple. De ce fait, si l’application s’exécute dans Azure, la configuration de l’application (app settings) pourra être lue dans les ServiceConfiguration et si elle s’exécute dans un serveur web classique, elle pourra lire dans le web.config :
Code Snippet
- public static string Get(string key)
- {
- if (RoleEnvironment.IsAvailable)
- {
- return RoleEnvironment.GetConfigurationSettingValue(key);
- }
- else
- {
- return ConfigurationManager.AppSettings[key];
- }
- }
6. Bug avec Ajax “Specified argument was out of the range of valid values. Paremeter name: utcDate”
Si votre application utilise des composants Ajax, il se peut que vous soyez confrontés au problème suvant :
Code Snippet
- <!--
- [ArgumentOutOfRangeException]: Specified argument was out of the range of valid values.
- Parameter name: utcDate
- at System.Web.HttpCachePolicy.UtcSetLastModified(DateTime utcDate)
- at System.Web.HttpCachePolicy.SetLastModified(DateTime date)
- at System.Web.Handlers.AssemblyResourceLoader.System.Web.IHttpHandler.ProcessRequest(HttpContext context)
- at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
- at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
- -->
Un problème avec le paramètre utcDate serait la cause…
La raison : il se trouve que lors du déploiement de l’application, le package a de fortes chances d’être en avance sur son temps (La France a 2h d’avance sur l’UTC) car il aura été généré sur votre poste en France… Ajax ne doit pas trop aimé ça.
Pour résoudre ce problème, deux solutions.
1) Attendre 2h…
2) comme énoncé sur ce thread, il faut copier tout le contenu CSS de l’AjaxControlToolKit dans votre projet et mettre le build action en Content.