GNU/Linux >> Tutoriales Linux >  >> Linux

Errores clásicos de Path.DirectorySeparatorChar al pasar de .NET Core en Windows a Linux

Un paso importante para trasladar mi blog a Azure fue considerar obtener esta aplicación .NET, ahora .NET Core aplicación, para ejecutarse en Linux Y Windows. Ser capaz de ejecutarse en Linux y Windows nos daría a mí y a otros una opción más amplia de hospedaje, permitiría el hospedaje en contenedores de Linux y, para mí, me ahorraría dinero, ya que el hospedaje de Linux tiende a ser más económico, incluso en Azure.

Conseguir algo para compilar en Linux no es lo mismo que conseguir que se ejecute, por supuesto.

Además, algo podría funcionar bien en un contexto y no en otro. Mi socio Mark (poppastring) en este proyecto ha estado ejecutando este código en .NET durante un tiempo, aunque en Windows. Además, se ejecuta en IIS en /blog como una subaplicación. Ejecuto Linux en Azure, y aunque también estoy en /blog, mi sitio está detrás de Azure Front Door como un proxy inverso que maneja el dominio/blog/ruta y reenvía a lo largo del dominio/ruta a la aplicación.

Para resumir, funcionó tanto en su blog como en el mío, hasta que intenté publicar una nueva publicación en el blog.

Utilizo Open Live Writer (versión de código abierto de Windows Live Writer) para realizar una llamada API MetaWebLog a mi blog. Hay varias llamadas para cargar los archivos binarios (PNG) y se devuelve una ruta. Un binario recién cargado puede tener una ruta como https://hanselman.com/blog/content/binary/something.png. El archivo en el disco (desde la perspectiva del servidor) podría ser d:\lo que sea\sitio\wwwroot\content\binary\something.png.

Este es ASP.NET 1 de 15 años, por lo que hay algunas cosas idiomáticas que no son modernas, además se agregaron las variables para la depuración de la ventana de visualización, pero ¿ve el problema potencial?

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

Ese '\\' está haciendo una gran suposición. Uno razonable en 2003, pero grande hoy. Está recortando una barra invertida del comienzo de la cadena pasada. Luego, el constructor de Uri comienza a generar cosas y mezclamos y combinamos \ y / y terminamos con URL truncadas que no se resuelven.

Las suposiciones sobre los separadores de ruta son un problema importante cuando se mueve el código .NET a Linux o Mac, y a menudo se ocultan profundamente en métodos de utilidad como este.

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

Podemos usar la constante correcta para Path.DirectorySeparatorChar, o el poco conocido AltDirectorySeparatorChar ya que Windows admite ambos. Es por eso que este código funciona en la implementación de Windows de Mark, pero no falla hasta que se ejecuta en mi implementación de Linux.

DOCUMENTOS: Tenga en cuenta que Windows admite la barra diagonal (que devuelve el campo AltDirectorySeparatorChar) o la barra invertida (que devuelve el campo DirectorySeparatorChar) como caracteres separadores de ruta, mientras que los sistemas basados ​​en Unix solo admiten la barra diagonal.

También vale la pena señalar que cada sistema operativo tiene diferentes caracteres de ruta no válidos. Tengo algunas imágenes con formato 404 porque algunos de mis archivos tienen espacios iniciales en Linux pero guiones bajos en Windows. Más sobre eso (y otros errores/comportamientos oscuros pero divertidos) en futuras publicaciones.

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

Aquí hay algunos artículos que ya he escrito sobre el tema de las migraciones heredadas a la nube.

  • Migración de este blog a Azure
  • Migraciones a la nube en el mundo real:traslado de una serie de sitios de 17 años de edad de bare metal a Azure
  • Tratar con las URL base de la aplicación y la generación de enlaces de Razor mientras se alojan aplicaciones web ASP.NET detrás de Proxies inversos
  • Actualización de un sitio web de ASP.NET Core 2.2 a .NET Core 3.1 LTS
  • Mover un ASP.NET Core de Azure App Service en Windows a Linux probando primero en WSL y Docker

Si encuentra algún problema con este blog como

  • Enlaces rotos y 404 donde no los esperarías
  • Imágenes rotas, imágenes de cero bytes, imágenes gigantes
  • Rarezas generales

¡Preséntelos aquí https://github.com/shanselman/hanselman.com-bugs y avíseme!

Ah, y suscríbete a mi YouTube y cuéntaselo a tus amigos. Es encantador.

Patrocinador: ¿Ya intentaste desarrollar en Rider? Este IDE multiplataforma rápido y rico en funciones mejora su código para aplicaciones .NET, ASP.NET, .NET Core, Xamarin y Unity en Windows, Mac y Linux.


Linux
  1. Apague la máquina de Windows desde la terminal de Linux

  2. Cómo eliminar versiones anteriores de .NET Core de Linux (CentOS 7.1)

  3. NuGet para .NET Core en Linux

  4. Copie el archivo de Linux a Windows Share con C# (.NET core)

  5. copiar archivo de windows a linux

Pasar de Windows a Linux - Administración de discos

Alejándose de Windows - Comienza

Soporte oficial para la depuración remota de una aplicación .NET Core Linux en WSL2 desde Visual Studio en Windows

Mover un ASP.NET Core de Azure App Service en Windows a Linux probando primero en WSL y Docker

Depuración remota de una aplicación .NET Core Linux en WSL2 desde Visual Studio en Windows

Cómo compilar la aplicación .NET Core para Linux en una máquina con Windows