tag route net data asp all c# asp.net-core kestrel-http-server

c# - route - forms asp net core



Modificar la respuesta de archivo estático en ASP.NET Core (1)

Sí, la secuencia predeterminada proporcionada es de solo lectura porque los datos solo se almacenan temporalmente por un breve momento y se descargan al cliente. Por lo tanto, no puede rebobinarlo o leerlo.

Su segundo intento no funciona porque la secuencia original nunca se procesa. Reemplazó la secuencia de cuerpo de la respuesta por completo con MemoryStream y MemoryStream la solicitud original, por lo que nunca hay algo escrito en ella y el cliente espera para siempre.

No debe olvidar que la transmisión al cliente está dentro de la transmisión original, no puede simplemente reemplazarla por otra cosa.

Después de llamar a await next() , debe leer los datos del MemoryStream y luego escribirlos en la transmisión original.

app.Use(async (context, next) => { var originalStream = context.Response.Body; var memoryStream = new MemoryStream(); context.Response.Body = memoryStream; await next(); // Here you must read the MemoryStream, modify it, then write the // result into "originalStream" });

Observación

Pero tenga en cuenta que esta solución almacenará toda la respuesta en la memoria de los servidores, por lo que si envía archivos grandes, esto degenerará significativamente el rendimiento de su aplicación ASP.NET Core, especialmente si sirve archivos de varios megabytes de tamaño y causa. la recolección de basura se activará más a menudo.

Y esto no solo afectaría a sus archivos estáticos, sino también a todas sus solicitudes habituales, ya que se llama a MVC Middleware después del middleware de archivos estáticos.

Si realmente desea modificar una sola (o una lista de archivos) en cada solicitud, prefiero sugerir que lo haga dentro de un controlador y enrute ciertos archivos allí. Recuerde, si el archivo dado no es encontrado por el middleware de archivos estáticos, llamará al siguiente en la cadena hasta que llegue al middleware de mvc.

Simplemente configure una ruta allí que coincida con un archivo o carpeta específica y enrute a un controlador. Lea el archivo en el controlador y escríbalo en la secuencia de respuesta o simplemente devuelva el nuevo vapor (utilizando return File(stream, contentType);

Sirvo un montón de archivos estáticos en mi aplicación con app.UseStaticFiles() . Me gustaría agregar un margen adicional en la respuesta para un archivo HTML particular antes de enviarlo. Mi primer intento fue agregar middleware como este antes del middleware de archivos estáticos:

app.Use(async (context, next) => { await next(); // Modify the response here });

Sin embargo, esto no funciona, ya que no puedo leer la secuencia de respuesta de lectura, está utilizando FrameResponseStream de Kestrel debajo del capó, que es ilegible.

Entonces, pensé que podría reemplazar la secuencia de cuerpo de respuesta con un MemoryStream que podría escribir:

app.Use(async (context, next) => { context.Response.Body = new MemoryStream(); await next(); // Modify the response here });

Pero esto solo hace que la solicitud nunca se complete; pasa por todas las etapas de interconexión, pero nunca devuelve ningún encabezado al navegador.

Entonces, ¿hay alguna manera de que pueda modificar la respuesta que produce el StaticFileMiddleware ?

Actualizar

Como el archivo HTML en cuestión es pequeño (765 bytes), el consumo de memoria no es una preocupación. Sin embargo, cualquier intento de leer / modificar la respuesta sigue causando el mismo problema que antes (no se devuelve nada). Más explícitamente, esto es lo que se está haciendo:

app.Use(async (context, next) => { var originalStream = context.Response.Body; var bufferStream = new MemoryStream(); context.Response.Body = bufferStream; await next(); bufferStream.Seek(0, SeekOrigin.Begin); if (/* some condition */) { var reader = new StreamReader(bufferStream); var response = await reader.ReadToEndAsync(); // The response string is modified here var writer = new StreamWriter(originalStream); await writer.WriteAsync(response); } else { await bufferStream.CopyToAsync(originalStream); } });

Los archivos que golpean la condición else se devuelven bien, pero el archivo particular en la condición if causa problemas. Incluso si no modifico la transmisión en absoluto, aún se cuelga.