GNU/Linux >> Linux Esercitazione >  >> Linux

Il classico Path.DirectorySeparatorChar ottiene risultati quando si passa da .NET Core su Windows a Linux

Un passaggio importante per spostare il mio blog in Azure è stato considerare l'idea di ottenere questa app .NET, ora un .NET Core app, per funzionare su Linux E Windows. Essere in grado di funzionare su Linux e Windows darebbe a me e ad altri una scelta più ampia di hosting, consentirebbe l'hosting in contenitori Linux e, per me, mi farebbe risparmiare denaro poiché l'hosting Linux tende ad essere più economico, anche su Azure.

Ottenere qualcosa da compilare su Linux non è lo stesso che farlo funzionare, ovviamente.

Inoltre, qualcosa potrebbe funzionare bene in un contesto e non in un altro. Il mio partner Mark (poppastring) in questo progetto esegue questo codice su .NET da un po', anche se su Windows. Inoltre funziona su IIS in /blog come sottoapplicazione. Corro su Linux su Azure e, mentre sono anche su /blog, il mio sito è dietro la porta principale di Azure come proxy inverso che gestisce il dominio/blog/percorso e inoltra lungo il dominio/percorso all'app.

Per farla breve, ha funzionato sia sul suo blog che sul mio, finché non ho provato a pubblicare un nuovo post sul blog.

Uso Open Live Writer (versione open source di Windows Live Writer) per effettuare una chiamata API MetaWebLog al mio blog. Ci sono più chiamate per caricare i file binari (PNG) e viene restituito un percorso. Un file binario appena caricato potrebbe avere un percorso come https://hanselman.com/blog/content/binary/something.png. Il file su disco (dal punto di vista del server) potrebbe essere d:\whatever\site\wwwroot\content\binary\something.png.

Questo è ASP.NET 1 di 15 anni, quindi ci sono alcune cose idiomatiche in corso che non sono moderne, inoltre le var sono state aggiunte per il debug della finestra di controllo, ma vedi il potenziale problema?

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

Che '\\' sta facendo un grande presupposto. Una ragionevole nel 2003, ma grande oggi. Sta tagliando una barra rovesciata dall'inizio della stringa passata. Quindi il costruttore Uri inizia a venire e stiamo mescolando e abbinando \ e / e finiamo con URL troncati che non si risolvono.

I presupposti sui separatori di percorso sono uno dei problemi principali quando si sposta il codice .NET su Linux o Mac e spesso sono sepolti in profondità in metodi di utilità come questo.

var relPath = fullPath.Replace(contentLocation, String.Empty).TrimStart(Path.DirectorySeparatorChar);

Possiamo usare la costante corretta per Path.DirectorySeparatorChar o il poco noto AltDirectorySeparatorChar poiché Windows supporta entrambi. Ecco perché questo codice funziona sulla distribuzione Windows di Mark ma non si interrompe finché non viene eseguito sulla mia distribuzione Linux.

Documenti: Si noti che Windows supporta la barra (restituita dal campo AltDirectorySeparatorChar) o la barra rovesciata (restituita dal campo DirectorySeparatorChar) come caratteri di separazione del percorso, mentre i sistemi basati su Unix supportano solo la barra.

Vale anche la pena notare che ogni sistema operativo ha diversi caratteri di percorso non validi. Ho alcune immagini 404'ed perché alcuni dei miei file hanno spazi iniziali su Linux ma sottolineature su Windows. Maggiori informazioni su questo ) (e altri bug/comportamenti oscuri ma divertenti) nei post futuri.

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

Ecco alcuni articoli che ho già scritto sull'argomento delle migrazioni legacy al cloud.

  • Migrazione di questo blog in Azure
  • Migrazioni cloud nel mondo reale:spostamento di una serie di siti di 17 anni fa dal bare metal ad Azure
  • Gestione degli URL di base dell'applicazione e della generazione di collegamenti Razor durante l'hosting di app Web ASP.NET dietro proxy inverso
  • Aggiornamento di un sito Web ASP.NET Core 2.2 a .NET Core 3.1 LTS
  • Spostamento di un ASP.NET Core dal Servizio app di Azure su Windows a Linux eseguendo prima il test in WSL e Docker

Se trovi problemi con questo blog come

  • Collegamenti interrotti e 404 dove non te li aspetteresti
  • Immagini interrotte, immagini a zero byte, immagini giganti
  • Stranarità generale

Per favore archiviali qui https://github.com/shanselman/hanselman.com-bugs e fammi sapere!

Oh, e per favore iscriviti al mio YouTube e dillo ai tuoi amici. È bello.

Sponsor: Hai già provato a sviluppare in Rider? Questo IDE multipiattaforma veloce e ricco di funzionalità migliora il codice per le applicazioni .NET, ASP.NET, .NET Core, Xamarin e Unity su Windows, Mac e Linux.


Linux
  1. Utilizzando Windows DLL da Linux

  2. Spegni la macchina Windows dal terminale Linux

  3. Come rimuovere le versioni precedenti di .NET Core da Linux (CentOS 7.1)

  4. Copia il file da Linux a Windows Condividi con C# (.NET core)

  5. scp da Linux remoto a Windows locale con spazi nel percorso locale

Passaggio da Windows a Linux - Gestione del disco

Allontanarsi da Windows - Inizia

Supporto ufficiale per il debug remoto di un'app Linux .NET Core in WSL2 da Visual Studio su Windows

Spostamento di un ASP.NET Core dal servizio app di Azure in Windows a Linux eseguendo prima il test in WSL e Docker

Debug remoto di un'app Linux .NET Core in WSL2 da Visual Studio in Windows

Come compilare l'app .NET Core per Linux in un computer Windows