2010-12-03 20 views
5

Por lo tanto, ASP.net tiene el concepto de una 'raíz de aplicación'. Es la parte de la ruta de la URL que corresponde al directorio raíz que se establece para una aplicación en IIS. El caracter tilde (~) se asigna a esa ruta en las URL de ASP.net, por lo que si ASP.net cree que mi aplicación está en/MyApp, algo en un control de servidor cuya URL doy como "~/Scripts/script.js" resolverá (y se enviará al navegador como) "/MyApp/Scripts/script.js".¿Cambiar la raíz de la aplicación ASP.net?

Esto es una posibilidad remota, pero ¿hay alguna manera de que pueda cambiar la raíz de esta aplicación arbitrariamente? De hecho, tengo una aplicación en un directorio debajo de otra y estoy usando la reescritura de URL para que esté disponible sin el prefijo del nombre del directorio, pero ASP.net siempre está prefijando el nombre del directorio en cualquier lugar que use ~. Realmente quiero ~ resolver una cadena vacía. ¿Puede uno hacerlo?

Respuesta

6

Debería poder cambiar la semántica de lo ~ a los mapas escribiendo un VirtualPathProvider personalizado. Esto es lo que podría parecer. He probado esto en un caso simple, pero probablemente necesite pulido.

Le sugiero que juegue con ella una aplicación de prueba simple antes de moverla a su escenario real. Eso hará que sea más fácil aislar los problemas y repetirlos.

using System; 
using System.Collections; 
using System.IO; 
using System.Linq; 
using System.Web; 
using System.Web.Caching; 
using System.Web.Hosting; 

public class TildeModifyingVPP : VirtualPathProvider { 

    // Change this to what you want ~ to map to 
    private const string PseudoRoot = "~/PseudoAppRoot/"; 

    public static void AppInitialize() { 
     HostingEnvironment.RegisterVirtualPathProvider(new TildeModifyingVPP()); 
    } 

    private string ResolvePath(string virtualPath) { 
     // Make it app relative, i.e. ~/... 
     virtualPath = VirtualPathUtility.ToAppRelative(virtualPath); 

     // Change the ~/ to our pseudo root 
     return PseudoRoot + virtualPath.Substring(2); 
    } 

    public override bool FileExists(string virtualPath) { 
     return base.FileExists(ResolvePath(virtualPath)); 
    } 

    public override VirtualFile GetFile(string virtualPath) { 
     return new DelegatingVirtualFile(virtualPath, base.GetFile(ResolvePath(virtualPath))); 
    } 

    public override bool DirectoryExists(string virtualDir) { 
     return base.DirectoryExists(ResolvePath(virtualDir)); 
    } 

    public override VirtualDirectory GetDirectory(string virtualDir) { 
     return new DelegatingVirtualDirectory(virtualDir, base.GetDirectory(ResolvePath(virtualDir))); 
    } 

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) { 
     virtualPathDependencies = virtualPathDependencies.Cast<string>().Select(vpath => ResolvePath(vpath)); 
     return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); 
    } 
} 

class DelegatingVirtualFile : VirtualFile { 
    private VirtualFile _underlyingFile; 
    public DelegatingVirtualFile(string virtualPath, VirtualFile underlyingFile): base(virtualPath) { 
     _underlyingFile = underlyingFile; 
    } 

    public override Stream Open() { 
     return _underlyingFile.Open(); 
    } 
} 

class DelegatingVirtualDirectory : VirtualDirectory { 
    private VirtualDirectory _underlyingDir; 
    public DelegatingVirtualDirectory(string virtualPath, VirtualDirectory underlyingDir) 
     : base(virtualPath) { 
     _underlyingDir = underlyingDir; 
    } 

    public override IEnumerable Children { get { return _underlyingDir.Children; } } 
    public override IEnumerable Directories { get { return _underlyingDir.Directories; } } 
    public override IEnumerable Files { get { return _underlyingDir.Files; } } 
} 
1

Así que tiene una configuración de sitio en IIS, y luego ha creado una "Aplicación" dentro del sitio. ¿Desea que la "Aplicación" resuelva sus CSS/JavaScript/Imágenes en el directorio raíz del sitio, no en la subaplicación?

¿Para qué necesitas poner la tilde para empezar?

¿Por qué no lo hacen

"/scripts/script.js" "/css/main.css"

Por lo que siempre viene desde el directorio raíz.

+0

Estoy de acuerdo y también uso de la misma manera sin la tilde. –

+0

Eso tendría 2 problemas. 1. Depuración; en mi servidor IIS local, realmente SÍ tengo el nombre de la aplicación en la ruta antes que el resto de la ruta, es solo en el cuadro directo que no. 2. ASP.net sigue redirigiendo en varios lugares (como con la autenticación de formularios), y utiliza la raíz de la aplicación como una base para hacia dónde redirigir. Después de ingresar sus credenciales e iniciar sesión, la autenticación de formularios ASP.net se redirigirá a ~/Whatever.aspx, por lo que aún necesita poder redefinir ~ para esas redirecciones. – Jez

+0

¿Los dos problemas son? – Phill

0

No podrás hacer lo que quieras con la forma en que configuraste tu sitio/aplicación. La raíz de la aplicación es solo eso, la ruta a la raíz de su aplicación. Si desea que su "sitio web" y su "aplicación" tengan "/" como raíz de la aplicación, deberá crear dos sitios web y hacer que escuchen diferentes encabezados de host (por ejemplo, mysite.com y myapp.mysite. com). De esta forma, la raíz de la aplicación es la raíz del sitio web, "/", y no la raíz de la carpeta de la aplicación.

Cuestiones relacionadas