martes, 29 de octubre de 2024

Directorio Virtual en IIS con netcore

Se tiene un sitio ejemplo https://MiSitio/home.aspx

Si queremos tener un directorio virtual en nuestra aplicacion para acceder a las evidencias guardadas en un directorio diferente al de nuestra aplicacion y acederlas desde nuestra aplicacion de la siguiente manera

https://MiSitio/Evidencias/imagen1.jpg

https://MiSitio/Evidencias/imagen2.png

https://MiSitio/Evidencias/evidencia1.pdf


En aplicaciones en NET Core montadas en el IIS crear un diretorio de la forma tradicional no es posible, acontinuacion explicamos el por que

Diferencias entre ASP.NET Framework y ASP.NET Core en IIS:

  1. Manejo de Solicitudes por IIS:
    • En ASP.NET Framework, IIS manejaba directamente la mayoría de las solicitudes, incluyendo archivos estáticos y recursos dentro de directorios virtuales. En ese modelo, IIS gestionaba tanto las solicitudes a archivos estáticos (imágenes, CSS, JavaScript) como las solicitudes dinámicas (páginas ASP.NET o servicios).
    • ASP.NET Core, por otro lado, usa el AspNetCoreModule en IIS, que actúa como un proxy y redirige todas las solicitudes al servidor Kestrel integrado en ASP.NET Core, que es el que realmente maneja las solicitudes. IIS en este caso funciona más como un "front-end" que pasa las solicitudes a Kestrel, en lugar de manejar directamente archivos estáticos.
  2. Middleware en ASP.NET Core:
    • ASP.NET Core no maneja los directorios virtuales de la misma forma en que lo hace ASP.NET Framework. En lugar de delegar directamente a IIS, ASP.NET Core tiene un pipeline de middleware que se encarga de manejar las solicitudes. Esto significa que debes configurar explícitamente en el middleware qué rutas o directorios son accesibles como archivos estáticos.
    • Si quieres que un directorio virtual sea accesible en una aplicación ASP.NET Core, debes configurarlo en Startup.cs a través del middleware UseStaticFiles para decirle explícitamente a la aplicación qué carpetas deberían ser servidas como archivos estáticos.
  3. ASP.NET Core y el manejo de archivos estáticos:
    • En ASP.NET Framework, IIS podía acceder directamente a cualquier archivo en un directorio virtual definido, sin involucrar demasiado a la aplicación en ese proceso.
    • En ASP.NET Core, los archivos estáticos deben ser servidos explícitamente a través del middleware UseStaticFiles. El middleware controla qué carpetas son accesibles y bajo qué rutas virtuales. Esto ofrece más control y seguridad, pero también significa que los directorios virtuales tradicionales de IIS no funcionarán sin ser configurados en el middleware.
  4. Separación de Concerns (Responsabilidades):
    • En ASP.NET Core, el manejo de archivos estáticos es un componente explícito de la aplicación y forma parte del pipeline de solicitudes de la misma. El objetivo de ASP.NET Core es manejar las solicitudes de una manera más flexible y controlada, en lugar de delegar completamente a IIS para que maneje archivos estáticos.
    • Por eso, IIS no maneja directorios virtuales en ASP.NET Core de la manera tradicional, ya que todo el procesamiento de archivos estáticos se delega al servidor Kestrel (a menos que se configure de otra forma en el middleware de ASP.NET Core).

¿Por qué usar el middleware en Startup.cs?

  • Control: El middleware en Startup.cs te permite tener control completo sobre qué carpetas o rutas son accesibles. Puedes configurar rutas virtuales y servir archivos estáticos de diferentes carpetas de manera controlada.
  • Seguridad: Solo las carpetas que explícitamente defines en UseStaticFiles estarán disponibles al público. Esto reduce el riesgo de exposición accidental de archivos.
  • Flexibilidad: Puedes definir múltiples carpetas o rutas virtuales, aplicar reglas de caché, configurar qué tipos de archivos deben ser servidos, y más


Ejemplo Basico de Startup.cs


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Configurar archivos estáticos para la carpeta "wwwroot" (por defecto)
    app.UseStaticFiles();

    // Configurar archivos estáticos desde un directorio virtual (como Evidencias)
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(@"D:\EvidenciasDataSys\MisEvidencias"),
        RequestPath = "/Evidencias"
    });
}

Para crear una aplicación en .NET Core que solo sirva como un repositorio de imágenes y archivos PDF (sin mostrar páginas) y que funcione como una subaplicación en tu aplicación principal hecha en GeneXus, puedes seguir estos pasos:

1. Visual Studio Code (integrated terminal):

  • Si usas Visual Studio Code como tu editor, puedes abrir un terminal integrado en Visual Studio Code.
  • Abre VS Code, y en el menú superior selecciona Terminal > New Terminal.
  • Se abrirá un terminal en la parte inferior, y allí puedes ejecutar el comando para crear el proyecto:
  • dotnet new web -n FileRepositoryApp
    Crea el archivo Startup.cs en el proyecto generado

2. Configurar el manejo de archivos estáticos en Startup.cs:

En esta aplicación, solo necesitas configurar el middleware para servir archivos estáticos como imágenes y PDFs. Aquí te dejo un ejemplo de cómo debe ser el archivo Startup.cs:


using Microsoft.Extensions.FileProviders;

namespace FileRepositoryApp
{
    public class Startup(IConfiguration configuration)
    {
        private readonly IConfiguration _configuration = configuration;

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // Configuración básica para servir archivos estáticos desde wwwroot
            app.UseStaticFiles();

            // Obtener la ruta externa desde appsettings.json
            string? rutaExterna = _configuration["ExternalFilePath"];
            string? ExternalRequestPath = _configuration["ExternalRequestPath"];

            if (!string.IsNullOrEmpty(rutaExterna) && Directory.Exists(rutaExterna))
            {
                // Configuración para servir archivos desde una carpeta externa
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(rutaExterna),
                    RequestPath = ExternalRequestPath // Ruta virtual para acceder a la carpeta
                });
            }
            else
            {
                // Manejo del caso donde la ruta es nula o no existe
                throw new Exception("La ruta externa para los archivos estáticos no está configurada correctamente o no existe.");
            }
        }
    }
}

He creado un proyecto llamado FileRepositoryApp. Puedes ver el código y contribuir en mi repositorio de GitHub:
GitHub Repository

FileRepositoryApp

Descripción

FileRepositoryApp es una aplicación diseñada para servir archivos estáticos (como imágenes y PDFs) a través de una API personalizada. Utiliza configuraciones definidas en el archivo appsettings.json para controlar las rutas de los archivos servidos.

Configuración

appsettings.json

  • ExternalFilePath: Especifica la ruta física en el servidor donde están almacenados los archivos.

    {
      "ExternalFilePath": "C:\Files\ExternalContent"
    }
    

    En este ejemplo, los archivos se encuentran en C:\Files\ExternalContent.

  • ExternalRequestPath: Define la ruta virtual (URL) a través de la cual los archivos serán accesibles.

    {
      "ExternalRequestPath": "/content"
    }
    

    Los archivos estarán disponibles en una URL como https://misitio.com/content.

web.config

El archivo web.config es necesario si la aplicación está siendo desplegada en IIS. La sección aspNetCore se utiliza para configurar cómo el servidor IIS maneja la ejecución de la aplicación ASP.NET Core.

Ejemplo de configuración:

<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\FileRepositoryApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
  </system.webServer>
</configuration>
  • processPath: Especifica el proceso que inicia la aplicación (dotnet en este caso).
  • arguments: Indica el archivo de la aplicación que debe ser ejecutado (FileRepositoryApp.dll).
  • stdoutLogFile: Define dónde almacenar los logs de salida estándar.

Uso

  1. Configura las rutas en appsettings.json:

    • ExternalFilePath: Ruta física donde se almacenan los archivos.
    • ExternalRequestPath: Ruta virtual a través de la cual se acceden los archivos.
  2. Ejecuta la aplicación:

    • La aplicación puede ejecutarse localmente utilizando .NET Core o desplegarse en un servidor IIS.
    • Si está desplegada en IIS, asegúrate de que la sección aspNetCore esté correctamente configurada en el archivo web.config.
  3. Acceso a los archivos:

    • Los archivos almacenados en la carpeta física especificada en ExternalFilePath serán accesibles a través de la URL especificada en ExternalRequestPath.
    • Por ejemplo, si ExternalFilePath está configurado en C:\Files\ExternalContent y ExternalRequestPath está en /content, un archivo image.png en esa carpeta será accesible en:
      https://misitio.com/content/image.png
      

Instalación

  1. Clona este repositorio:

    git clone https://github.com/genexusmancilla/FileRepositoryApp.git
    
  2. Configura las rutas de los archivos en appsettings.json.

  3. Ejecuta la aplicación localmente o despliega en un servidor IIS.

Contribuciones

Si deseas contribuir a este proyecto, por favor, envía un pull request con una descripción detallada de los cambios propuestos.

Licencia

Este proyecto está bajo la licencia MIT.

martes, 16 de enero de 2024

Como agregar entrada al web.config desde Genexus al hacer el deploy


Al agregar o modificar un elemento del web.config en la carpeta web del modelo (RutaDeMiModelo\CSharpModel\Web\web.config) al hacer el deploy la configuracion por defecto de genexus, no considera lo que se ponga adicionalmente en el web.config

si queremos hacer un deploy y que el web.config tenga una personalizacion una forma es modificando los archivos 

  1. C:\Program Files (x86)\GeneXus\GeneXus17\Deploy\CSharp\GeneXus.csharp.Server.targets 
  2. C:\Program Files (x86)\GeneXus\GeneXus17\ApplicationServers\Templates\CSharpWeb\IIS_Base.stg



Vamos a modificar el archivo IIS_Base.stg agregando

 
location()::=<<
/*otro codigo existente */
$if (MiNuevaPropiedadSupport)$
	$locationNueva()$
$endif$
>>

locationNueva()::=<<
<location path="miruta">
 <system.webServer>
  <httpErrors errorMode="Detailed" />
 </system.webServer>
</location>
>>

Vamos a crear un arhivo MisPropiedades.prop y lo vamos a guardar en donde mas les sea de su agrado, en este archivo vamos a definir nuestras propiedades



<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <PropertyGroup>
  <!-- Agregar nuevas propiedades o sobrescribir propiedades existentes -->
  <MiNuevaPropiedadSupport>true</MiNuevaPropiedadSupport>		
 </PropertyGroup>
</Project>

Ahora vamos a modificar el archivo GeneXus.csharp.Server.targets

En la parte superior del archivo vamos agregar el Import a nuestro archivo MisPropiedades.props


<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
 <Import Project="$(GX_PROGRAM_DIR)\Packages\Gxpm\Platforms\GeneXus.CSharp.WorkflowEngine.targets"/>
 <Import Project="$(GX_PROGRAM_DIR)\Packages\Gxpm\Platforms\GeneXus.CSharp.WorkflowClient.targets"/>
 <Import Project="$(GX_PROGRAM_DIR)\Library\GAM\GAM_Backend\Net\GAM_Backend.targets" Condition="'$(IncludeGAMBackend)' == 'true'"/>
		
 <Import Project="MiRuta\MisPropiedades.props" Condition="Exists('MiRuta\MisPropiedades.props')" />
    //... Mas codigo existente

por ultimo vamos agregar codigo en el elemento <GenerateFromTemplate


<GenerateFromTemplate
 TemplateGroupFile="$(WebConfigTemplate)"
 TemplateName="generateConfig"
 Properties="
   DisplayName=$(ProjectName);
   Namespace=$(Namespace);
   IntegratedSecurity=$(IntegratedSecurity);
   RestEnabled=$(RestSupport);
   APIRestSupport=$(APIRestSupport);
   SDEnabled=$(SDSupport);
   HttpsEnabled=$(Https);
   IncludeQueryViewer=$(IncludeQueryViewer);
   WebNotificationSupport=$(WebNotificationSupport);
   HasWorkflow=$(HasWorkflow);
   HasBC=$(HasBCs);
   HasAPIs=$(HasAPIs);
   ChatbotSupport=$(ChatbotSupport);
   DeployOfflineReplicator=$(DeployOfflineReplicator);
   MiNuevaPropiedadSupport = $(MiNuevaPropiedadSupport);"

Ahora al hacer un Deploy va verificar la propiead y va agregar el fragmento que necesitamos en el web.config

Referencias:

StringTemplate

domingo, 9 de agosto de 2020

Redirect https con JavaScript

 

Hay varias formas de redirigir una pagina

aqui les dejo una forma para redirigir a una pagina

<html>

<head>

<body>


<!-- codigo que tu necesites --> 


<script type="text/javascript">  

function JSRedirectOnload() {

    if (window.location.protocol != "https") {  

    window.location = "https://" + window.location.hostname + '/wwpbaseobjects.home.aspx';

  }

}

if (window.addEventListener)

    window.addEventListener("load", JSRedirectOnload, false);

else if (window.attachEvent)

    window.attachEvent("onload", JSRedirectOnload);

else window.onload = JSRedirectOnload;

</script>

</body>

</html>


Referencias:

https://www.w3schools.com/js/js_window_location.asp

viernes, 28 de febrero de 2020

Como cambiar tu session timeout en IIS

En el IIS, seleccione uno de los sitios, seleccione la característica "ASP" y abra las propiedades



¡Ahora solo cambia el valor de propiedad "TimeOut", a el tiempo que prefieras!

por ultimo, verifique en Application Pool's la propiedad "idle timeout" con tu "session timeout"


jueves, 15 de noviembre de 2018

MaxWebConfigFileSizeInKB e IIS 10

Cuando el archivo web.config supera el tamaño de los 250kb el IIS genera el error
"No se puede leer el archivo de configuración porque supera el tamaño máximo de archivo iis"
"IIS - Cannot read configuration file because it exceeds the maximum file size"

para solucionarlo hay que agregar en regedit las siguientes entradas


Agregar la clave "Configuration"
Agregar el valor DWORD "MaxWebConfigFileSizeInKB"

En las siguientes ubicaciones:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\InetStp

domingo, 7 de mayo de 2017

Como Instalar Url rewrite en windows 10 IIS 10



Al intentar instalar Url Url ReWrite 2.0 en windows 10 IIS 10 no te deja instalarlo.

Para poder instalar el Url ReWrite 2.0 deberas seguir los siguientes pasos
  1. Abrir Regedit y ubicarse en HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp
  2. Editar la entrada "MajorVersion" y seleccionar la opcion "DECIMAL" despues poner el valor 9
  3. Pulsar F5 mientras estas en Regedit
  4. Ahora instala el modulo Url ReWrite 2.0
  5. Regresar el valor de "MajorVersion" al valor 10 "DECIMAL" 
  6. Pulsar F5 mientras estas en Regedit
  7. Cerrar el Regedit

martes, 31 de enero de 2017

Cómo establecer el maxAllowedContentLength a 500 MB


El límite de requests en .Net se puede configurar en dos propiedades en conjunto:
1. Web.Config/system.web/httpRuntime/maxRequestLength
Unidad de medida: kilobytes
Default value 4096 KB (4 MB)
Max. value 2147483647 KB (2 TB)

2. Web.Config/system.webServer/security/requestFiltering/maxAllowedContentLength (en bytes)
Unidad de medida: bytes
Default value 30000000 b (28.6 MB)
Max. value 4294967295 bytes (4 TB)


<system.web>
     <!-- El tamañano default es 4096 kilobytes (4 MB). Maximo Valor es 2147483647 KB (2 TB)-->
     <!-- 100 MB en  kilobytes -->
     <httpRuntime maxRequestLength="102400" />
   </system.web>
   <system.webServer>
     <security>
       <requestFiltering>        
         <!--El tamañano default es 30000000 bytes (28.6 MB). Maximo Valor es 4294967295 bytes (4 GB)-->
         <!-- 100 MB en bytes -->
         <requestLimits maxAllowedContentLength="104857600" />
       </requestFiltering>
     </security>
   </system.webServer>

Referencias:
https://www.iis.net/configreference/system.webserver/security/requestfiltering/requestlimits