GNU/Linux >> Znalost Linux >  >> Linux

Klasický Path.DirectorySeparatorChar se při přechodu z .NET Core na Windows na Linux vyskytl

Důležitým krokem při přesunu mého blogu do Azure bylo zvážit získání této aplikace .NET, nyní jádra .NET aplikace pro provoz na Linuxu A Windows. Možnost běžet na Linuxu a Windows by mně i ostatním poskytla širší výběr hostingu, umožnila by hostování v linuxových kontejnerech a pro mě by ušetřila peníze, protože Linux Hosting bývá levnější, dokonce i na Azure.

Získat něco ke kompilaci na Linuxu není totéž jako nechat to spustit, samozřejmě.

Navíc něco může fungovat dobře v jednom kontextu a v jiném ne. Můj partner Mark (poppastring) na tomto projektu již nějakou dobu spouští tento kód na .NET, i když na Windows. Navíc běží na IIS v /blog jako podaplikace. Běžím na Linuxu v Azure, a když jsem také na /blog, můj web je za předními dveřmi Azure jako reverzní proxy, která zpracovává doménu/blog/cestu a přeposílá podél domény/cesty do aplikace.

Stručně řečeno, fungovalo to jak na jeho blogu, tak na mém, dokud jsem nezkusil zveřejnit nový blogový příspěvek.

K volání MetaWebLog API na můj blog používám Open Live Writer (otevřená verze Windows Live Writer). Existuje několik volání pro nahrání binárních souborů (PNG) a je vrácena cesta. Nově nahraný binární soubor může mít cestu jako https://hanselman.com/blog/content/binary/something.png. Soubor na disku (z pohledu serveru) může být d:\whatever\site\wwwroot\content\binary\something.png.

Toto je 15 let staré ASP.NET 1, takže se zde dějí idiomatické věci, které nejsou moderní, navíc byly přidány vars pro ladění okna sledování, ale vidíte potenciální problém?

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

To '\\' je velký předpoklad. Rozumný v roce 2003, ale velký dnes. Je to oříznutí zpětného lomítka od začátku předávaného řetězce. Potom konstruktor Uri začne věci přicházet a my mícháme a porovnáváme \ a / a skončíme se zkrácenými adresami URL, které nelze vyřešit.

Předpoklady o oddělovačích cest jsou hlavním problémem při přesouvání kódu .NET do Linuxu nebo Macu a často jsou pohřbeny hluboko v utiltiy metodách, jako je tato.

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

Můžeme použít správnou konstantu pro Path.DirectorySeparatorChar nebo málo známý AltDirectorySeparatorChar, protože Windows podporuje obojí. To je důvod, proč tento kód funguje na Markově nasazení Windows, ale nezlomí se, dokud se nespustí v mém nasazení Linuxu.

DOKUMENTY: Všimněte si, že Windows podporuje buď dopředné lomítko (které vrací pole AltDirectorySeparatorChar) nebo zpětné lomítko (které vrací pole DirectorySeparatorChar) jako oddělovací znaky cesty, zatímco systémy založené na Unixu podporují pouze dopředné lomítko.

Za zmínku také stojí, že každý operační systém má jiné neplatné znaky cesty. Mám nějaké obrázky 404, protože některé z mých souborů mají v Linuxu úvodní mezery, ale ve Windows podtržítka. Více o tom (a dalších obskurních, ale zábavných chybách/chování) v budoucích příspěvcích.

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

Zde je několik článků, které jsem již napsal na téma starší migrace do cloudu.

  • Migrace tohoto blogu do Azure
  • Real World Cloud Migrations:Přesunutí 17 let staré série webů z holého kovu do Azure
  • Zacházení s adresami URL aplikační báze a generováním odkazů Razor při hostování webových aplikací ASP.NET za reverzními proxy servery
  • Aktualizace webu ASP.NET Core 2.2 na .NET Core 3.1 LTS
  • Přesun jádra ASP.NET z Azure App Service v systému Windows na Linux nejprve testováním ve WSL a Docker

Pokud narazíte na nějaké problémy s tímto blogem, jako

  • Nefunkční odkazy a 404 tam, kde byste je nečekali
  • Nefunkční obrázky, nulabajtové obrázky, obří obrázky
  • Obecná podivnost

Odešlete je prosím zde https://github.com/shanselman/hanselman.com-bugs a dejte mi vědět!

Jo, a prosím odebírejte můj YouTube a řekněte to svým přátelům. To je milé.

Sponzor: Zkoušeli jste už vývoj v Rideru? Toto rychlé a na funkce bohaté multiplatformní IDE vylepšuje váš kód pro aplikace .NET, ASP.NET, .NET Core, Xamarin a Unity na Windows, Mac a Linux.


Linux
  1. Vypněte počítač se systémem Windows z linuxového terminálu

  2. Podporuje .NET Core v Linuxu Visual Basic?

  3. NuGet pro .NET Core na Linuxu

  1. .NET core X509Store na linuxu

  2. zkopírujte soubor z Windows do Linuxu

  3. RDP z linuxu do windows

  1. Použití Windows DLL z Linuxu

  2. Jak odebrat předchozí verze .NET Core z Linuxu (CentOS 7.1)

  3. Zkopírujte soubor z linuxu do sdílení systému Windows pomocí C# (jádro .NET)