C# 更改ASP.net应用程序根目录?

C# 更改ASP.net应用程序根目录?,c#,asp.net,web-applications,web-config,C#,Asp.net,Web Applications,Web Config,因此,ASP.net具有“应用程序根”的概念。它是URL的路径部分,对应于为IIS中的应用程序设置的根目录。波浪号字符(~)映射到ASP.net URL中的路径,因此,如果ASP.net认为我的应用程序位于/MyApp,则服务器控件中的某个URL为“~/Scripts/script.js”的内容将解析为(并作为“/MyApp/Scripts/script.js”发送到浏览器 这是一个漫长的过程,但有没有一种方法可以任意更改此应用程序根目录?实际上,我在另一个目录下的某个目录中有一个应用程序,我正

因此,ASP.net具有“应用程序根”的概念。它是URL的路径部分,对应于为IIS中的应用程序设置的根目录。波浪号字符(~)映射到ASP.net URL中的路径,因此,如果ASP.net认为我的应用程序位于/MyApp,则服务器控件中的某个URL为“~/Scripts/script.js”的内容将解析为(并作为“/MyApp/Scripts/script.js”发送到浏览器


这是一个漫长的过程,但有没有一种方法可以任意更改此应用程序根目录?实际上,我在另一个目录下的某个目录中有一个应用程序,我正在使用URL重写使其可用,而不必在目录名前加前缀,但是ASP.net总是在我使用的任何地方加前缀。我真的想将~解析为空字符串。你能做到吗?

所以你在IIS中设置了一个站点,然后在站点中创建了一个“应用程序”。您希望“应用程序”将CSS/JavaScript/图像解析到站点的根目录,而不是子应用程序

你为什么一开始就要把瓷砖放进去

为什么不直接做呢

“/scripts/script.js” “/css/main.css”


因此,它总是来自根目录。

您将无法通过设置站点/应用程序的方式来执行您想要的操作。应用程序根就是应用程序根的路径。如果您希望您的“网站”和“应用程序”都以“/”作为应用程序根目录,则必须创建两个网站,并使它们侦听不同的主机标题(例如:mysite.com和myapp.mysite.com)。这样,应用程序根目录是网站“/”的根目录,而不是应用程序文件夹的根目录。

您应该能够通过编写自定义VirtualPathProvider来更改~映射到的内容的语义。下面是它可能的样子。我已经在一个简单的案例中对此进行了测试,但它可能需要改进

我建议您在将其移动到真实场景之前,先用一个简单的测试应用程序来测试它。这将使隔离问题和迭代问题变得更容易

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; } }
}
使用系统;
使用系统集合;
使用System.IO;
使用System.Linq;
使用System.Web;
使用System.Web.Caching;
使用System.Web.Hosting;
公共类TileDemodifyingVPP:VirtualPathProvider{
//将此更改为要映射到的对象
私有常量字符串PseudoRoot=“~/PseudoAppRoot/”;
公共静态void AppInitialize(){
HostingEnvironment.RegisterVirtualPathProvider(新的TildeModifyingVPP());
}
私有字符串解析路径(字符串虚拟路径){
//使其与应用程序相关,即~/。。。
virtualPath=virtualPath实用性。与之相关(virtualPath);
//将~/更改为我们的伪根
返回伪根+虚拟路径子字符串(2);
}
公共覆盖布尔文件存在(字符串virtualPath){
返回base.FileExists(ResolvePath(virtualPath));
}
公共重写VirtualFile GetFile(字符串virtualPath){
返回新的DelegatingVirtualFile(virtualPath,base.GetFile(ResolvePath(virtualPath));
}
公共覆盖布尔目录存在(字符串virtualDir){
返回base.DirectoryExists(ResolvePath(virtualDir));
}
公共重写VirtualDirectory GetDirectory(字符串virtualDir){
返回新的DelegatingVirtualDirectory(virtualDir,base.GetDirectory(ResolvePath(virtualDir)));
}
公共重写CacheDependency GetCacheDependency(字符串virtualPath、IEnumerable virtualPath Dependencies、DateTime utcStart){
virtualPathDependencies=virtualPathDependencies.Cast().Select(vpath=>ResolvePath(vpath));
返回base.GetCacheDependency(virtualPath、virtualPath Dependencies、utcStart);
}
}
类DelegatingVirtualFile:VirtualFile{
私有虚拟文件_underyingfile;
public DelegatingVirtualFile(字符串virtualPath,VirtualFile underyingfile):base(virtualPath){
_underyingfile=underyingfile;
}
公共覆盖流打开(){
返回_underyingfile.Open();
}
}
类DelegatingVirtualDirectory:VirtualDirectory{
私有虚拟目录_underyingdir;
public DelegatingVirtualDirectory(字符串virtualPath,VirtualDirectory underyingdir)
:base(虚拟路径){
_underlyngdir=underlyngdir;
}
公共重写IEnumerable子项{get{return}underlyingDir.Children;}
公共重写IEnumerable目录{get{return}underlyingDir.Directories;}}
公共重写IEnumerable文件{get{return _underyingdir.Files;}}
}

同意,我也使用相同的方法,不使用瓷砖。这将有两个问题。1.调试;在我的本地IIS服务器上,我实际上在路径中的应用程序名比路径的其余部分早,只是在live box中我没有。2.ASP.net仍然在不同的地方重定向(比如表单身份验证),并且它使用应用程序根作为重定向到哪里的基础。在您输入凭据并登录后,ASP.net forms authentication将重定向到~/Whatever.aspx-因此您仍然需要能够重新定义这些重定向。请在原始问题中解释您的设置,因为我有几个网站是作为一个主web应用程序开发的,还有1到2个额外的解决方案部署在主网站下作为应用程序。我对重定向没有任何问题。所有css/javascript/图像都来自根目录,而大多数页面重定向都使用tilde;也就是说,它不会造成任何破损。它将要做的是将应用程序目录名保留在URL中,即使URL重写也是如此,因为它将重定向到/Appname/Whatever.aspx。URL重写允许我重写对/whater.aspx的请求,使其实际转到/Appname/whater.aspx,但ASP.net仍然认为后者是被请求的,因此将重定向(例如从forms auth login)到/Appname/whater.aspx。再