Une étape importante dans le déplacement de mon blog vers Azure a été d'envisager d'obtenir cette application .NET, maintenant un .NET Core app, pour fonctionner sous Linux ET Windows. Pouvoir fonctionner sous Linux et Windows me donnerait, à moi et à d'autres, un plus grand choix d'hébergement, permettrait l'hébergement dans des conteneurs Linux et, pour moi, me ferait économiser de l'argent car l'hébergement Linux a tendance à être moins cher, même sur Azure.
Obtenir quelque chose à compiler sous Linux n'est pas la même chose que de le faire fonctionner, bien sûr.
De plus, quelque chose peut bien fonctionner dans un contexte et pas dans un autre. Mon partenaire Mark (poppastring) sur ce projet exécute ce code sur .NET depuis un certain temps, mais sur Windows. De plus, il s'exécute sur IIS dans /blog en tant que sous-application. Je cours sur Linux sur Azure, et bien que je sois également sur /blog, mon site se trouve derrière Azure Front Door en tant que proxy inverse qui gère le domaine/blog/chemin et transmet le long du domaine/chemin à l'application.
Pour faire court, cela a fonctionné à la fois sur son blog et sur le mien, jusqu'à ce que j'essaie de publier un nouveau billet de blog.
J'utilise Open Live Writer (version open source de Windows Live Writer) pour effectuer un appel d'API MetaWebLog sur mon blog. Il y a plusieurs appels pour télécharger les fichiers binaires (PNG) et un chemin est renvoyé. Un binaire nouvellement téléchargé peut avoir un chemin comme https://hanselman.com/blog/content/binary/something.png. Le fichier sur le disque (du point de vue du serveur) peut être d:\whatever\site\wwwroot\content\binary\something.png.
Il s'agit d'ASP.NET 1 vieux de 15 ans, il y a donc des trucs idiomatiques qui ne sont pas modernes, et les vars ont été ajoutés pour le débogage de la fenêtre de surveillance, mais voyez-vous le problème potentiel ?
private string GetAbsoluteFileUri(string fullPath, out string relFileUri)
{
var relPath = fullPath.Replace(contentLocation, "").TrimStart('\\');
var relUri = new Uri( relPath, UriKind.Relative);
relFileUri = relUri.ToString();
return new Uri(binaryRoot, relPath).ToString();
}
Ce '\\' fait une grande hypothèse. Un raisonnable en 2003, mais un grand aujourd'hui. Il coupe une barre oblique inverse au début de la chaîne transmise. Ensuite, le constructeur Uri commence à venir et nous mélangeons et faisons correspondre \ et / et nous nous retrouvons avec des URL tronquées qui ne se résolvent pas.
Les hypothèses sur les séparateurs de chemin sont un problème majeur lors du déplacement du code .NET vers Linux ou Mac, et il est souvent enfoui profondément dans des méthodes utilitaires comme celle-ci.
var relPath = fullPath.Replace(contentLocation, String.Empty).TrimStart(Path.DirectorySeparatorChar);
Nous pouvons utiliser la constante correcte pour Path.DirectorySeparatorChar, ou le peu connu AltDirectorySeparatorChar car Windows prend en charge les deux. C'est pourquoi ce code fonctionne sur le déploiement Windows de Mark, mais ne s'interrompt pas tant qu'il ne s'exécute pas sur mon déploiement Linux.
DOCS : Notez que Windows prend en charge la barre oblique (qui est renvoyée par le champ AltDirectorySeparatorChar) ou la barre oblique inverse (qui est renvoyée par le champ DirectorySeparatorChar) comme caractères de séparation de chemin, tandis que les systèmes basés sur Unix ne prennent en charge que la barre oblique.
Il convient également de noter que chaque système d'exploitation a différents caractères de chemin non valides. J'ai des images 404 parce que certains de mes fichiers ont des espaces principaux sous Linux mais des soulignements sous Windows. Plus d'informations à ce sujet (et d'autres bugs/comportements obscurs mais amusants) dans les prochains articles.
static void Main()
{
Console.WriteLine($"Path.DirectorySeparatorChar: '{Path.DirectorySeparatorChar}'");
Console.WriteLine($"Path.AltDirectorySeparatorChar: '{Path.AltDirectorySeparatorChar}'");
Console.WriteLine($"Path.PathSeparator: '{Path.PathSeparator}'");
Console.WriteLine($"Path.VolumeSeparatorChar: '{Path.VolumeSeparatorChar}'");
var invalidChars = Path.GetInvalidPathChars();
Console.WriteLine($"Path.GetInvalidPathChars:");
for (int ctr = 0; ctr < invalidChars.Length; ctr++)
{
Console.Write($" U+{Convert.ToUInt16(invalidChars[ctr]):X4} ");
if ((ctr + 1) % 10 == 0) Console.WriteLine();
}
Console.WriteLine();
}
Voici quelques articles que j'ai déjà écrits sur le sujet des migrations héritées vers le cloud.
- Migration de ce blog vers Azure
- Migrations vers le cloud dans le monde réel :déplacement d'une série de sites de 17 ans du système nu vers Azure
- Traitement des URL de base d'application et de la génération de liens Razor lors de l'hébergement d'applications Web ASP.NET derrière des proxys inverses
- Mise à jour d'un site Web ASP.NET Core 2.2 vers .NET Core 3.1 LTS
- Déplacer un noyau ASP.NET d'Azure App Service sur Windows vers Linux en testant d'abord dans WSL et Docker
Si vous rencontrez des problèmes avec ce blog, aimez
- Liens rompus et 404 là où vous ne les attendriez pas
- Images brisées, images de zéro octet, images géantes
- Bizarrerie générale
Veuillez les déposer ici https://github.com/shanselman/hanselman.com-bugs et faites le moi savoir !
Oh, et s'il vous plaît, abonnez-vous à mon YouTube et parlez-en à vos amis. C'est adorable.
Parrain : Avez-vous déjà essayé de développer dans Rider ? Cet IDE multiplateforme rapide et riche en fonctionnalités améliore votre code pour les applications .NET, ASP.NET, .NET Core, Xamarin et Unity sous Windows, Mac et Linux.