GNU/Linux >> Linux の 問題 >  >> Linux

Windows 上の .NET Core から Linux に移行するときにクラシック Path.DirectorySeparatorChar が発生する

ブログを Azure に移行する際の重要なステップは、.NET Core になったこの .NET アプリの取得を検討することでした。アプリ、Linux および Windows で実行します。 Linux と Windows で実行できるようになれば、ホスティングの選択肢が広がり、Linux コンテナーでのホスティングが可能になります。また、Linux ホスティングは Azure でも安くなる傾向があるため、お金を節約できます。

もちろん、Linux で何かをコンパイルすることは、それを実行することと同じではありません。

さらに、何かが 1 つのコンテキストでうまく動作し、別のコンテキストではうまく動作しない場合があります。このプロジェクトの私のパートナーである Mark (poppastring) は、Windows ではありますが、しばらくの間 .NET でこのコードを実行しています。さらに、サブアプリケーションとして /blog の IIS を実行しています。私は Linux on Azure で実行しています。また、/blog も使用していますが、私のサイトは、ドメイン/ブログ/パスを処理し、ドメイン/パスに沿ってアプリに転送するリバース プロキシとして Azure Front Door の背後にあります。

簡単に言えば、新しいブログ投稿を投稿しようとするまで、彼のブログと私の両方のブログで機能していました。

Open Live Writer (Windows Live Writer のオープン ソース バージョン) を使用して、ブログへの MetaWebLog API 呼び出しを行います。バイナリ (PNG) をアップロードするための複数の呼び出しがあり、パスが返されます。新しくアップロードされたバイナリには、https://hanselman.com/blog/content/binary/something.png のようなパスがある場合があります。ディスク上のファイル (サーバーの観点から) は、d:\whatever\site\wwwroot\content\binary\something.png である可能性があります。

これは 15 年前の ASP.NET 1 であるため、最新ではないいくつかの慣用的なことが行われています。また、ウォッチ ウィンドウのデバッグ用に変数が追加されていますが、潜在的な問題はありますか?

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

その「\\」は大きな仮定をしています。 2003 年には妥当な結果でしたが、今日では大きな問題です。渡された文字列の先頭からバックスラッシュをトリミングしています。次に、Uri コンストラクターが処理を開始し、\ と / を組み合わせて一致させ、最終的には解決されない切り捨てられた URL になります。

.NET コードを Linux や Mac に移行する際の最大の問題は、パス セパレーターに関する想定であり、このようなユーティリティ メソッドの奥深くに埋もれていることがよくあります。

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

Path.DirectorySeparatorChar の正しい定数、または Windows が両方をサポートしているためあまり知られていない AltDirectorySeparatorChar を使用できます。 そのため、このコードは Mark の Windows 展開では機能しますが、私の Linux 展開では実行されるまで壊れません。

<ブロック引用>

ドキュメント: Windows はスラッシュ (AltDirectorySeparatorChar フィールドによって返される) またはバックスラッシュ (DirectorySeparatorChar フィールドによって返される) をパス区切り文字としてサポートしますが、Unix ベースのシステムはスラッシュのみをサポートすることに注意してください。

OS ごとに無効なパス文字が異なることにも注意してください。一部のファイルには、Linux では先頭にスペースがあり、Windows ではアンダースコアがあるため、404 で処理された画像があります。 )(およびその他のあいまいだが楽しいバグ/動作) については、今後の投稿で詳しく説明します。

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

クラウドへの従来の移行について、私がすでに書いた記事をいくつか紹介します。

  • このブログを Azure に移行する
  • Real World Cloud Migrations:17 年前の一連のサイトをベア メタルから Azure に移行する
  • リバース プロキシの背後で ASP.NET Web アプリをホストしながら、アプリケーション ベース URL と Razor リンク生成を処理する
  • ASP.NET Core 2.2 Web サイトを .NET Core 3.1 LTS に更新する
  • まず WSL と Docker でテストして、ASP.NET Core を Windows 上の Azure App Service から Linux に移行する

このブログで次のような問題が見つかった場合は

  • 予期しないリンク切れと 404
  • 壊れた画像、ゼロ バイトの画像、巨大な画像
  • 一般的な奇妙さ

ここにファイルしてください https://github.com/shanselman/hanselman.com-bugs そして私に知らせてください!

ああ、私のYouTubeを購読して、友達に教えてください.素敵です。

スポンサー: Riderでの開発はもう試しましたか?この高速で機能豊富なクロスプラットフォーム IDE は、Windows、Mac、および Linux 上の .NET、ASP.NET、.NET Core、Xamarin、および Unity アプリケーションのコードを改善します。


Linux
  1. Linux ターミナルから Windows マシンをシャットダウンする

  2. Linux 上の .NET Core 用 NuGet

  3. Linux 上の .NET コア X509Store

  1. Linux から Windows DLL を使用する

  2. Visual Basic は Linux 上の .NET Core でサポートされていますか?

  3. Linux から Windows への RDP

  1. Linux (CentOS 7.1) から以前のバージョンの .NET Core を削除する方法

  2. C#(.NETコア)を使用して、LinuxからWindows共有にファイルをコピーします

  3. Windows から Linux にファイルをコピーする