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

发布于 2024-10-05 13:22:28 字数 374 浏览 3 评论 0原文

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

这是一个很遥远的事情,但是有没有办法可以任意更改这个应用程序根目录?实际上,我在另一个应用程序的目录下有一个应用程序,并且我正在使用 URL 重写来使其可用,而无需在目录名中添加前缀,但 ASP.net 始终在我使用 ~ 的任何地方为目录名添加前缀。我真的想让 ~ 解析为空字符串。一个人能做到吗?

So, ASP.net has the concept of an 'application root'. It is the path part of the URL that corresponds to the root directory that is set for an application in IIS. The tilde character (~) maps to that path in ASP.net URLs, so if ASP.net thinks my application is at /MyApp, something in a server control whose URL I give as "~/Scripts/script.js" will resolve to (and be sent to the browser as) "/MyApp/Scripts/script.js".

This is a long shot, but is there a way I can change this application root arbitrarily? I actually have an app in a directory under another one and I'm using URL rewriting to make it available without prefixing the directory name, but ASP.net is always prefixing the dir name anyway anywhere I use ~. I really want to make ~ resolve to an empty string. Can one do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扬花落满肩 2024-10-12 13:22:28

您应该能够通过编写自定义 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; } }
}

You should be able to change the semantic of what ~ maps to by writing a custom VirtualPathProvider. Here is what it might look like. I have tested this on a simple case, but it probably needs polishing.

I suggest you play around with it an a simple test app before you move it to your real scenario. That'll make it easier to isolate issues and iterate on it.

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; } }
}
辞取 2024-10-12 13:22:28

因此,您在 IIS 中设置了一个站点,然后在该站点内创建了一个“应用程序”。您希望“应用程序”将 CSS/JavaScript/Images 解析到网站的根目录,而不是子应用程序?

为什么首先需要输入波浪号?

为什么不直接做

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

所以它总是来自根目录。

So you have a Site setup in IIS, and then you've created a "Application" inside the site. You want the "Application" to resolve your CSS/JavaScript/Images to the root directory of the site, not to the sub Application?

Why do you need to put the tilde in to begin with?

Why not just do

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

So it always comes from the root directory.

心欲静而疯不止 2024-10-12 13:22:28

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

You won't be able to do what you want with the way you have your site/application set up. The application root is just that, the path to the root of your application. If you want your "website" and your "app" to both have "/" as the application root, you'll have to create two websites and make them listen to different host headers (ex: mysite.com and myapp.mysite.com). This way the application root is the root of the website, "/", and not the root of the application folder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文