繁体   English   中英

当应用程序根目录不同时,不会调用MVC VirtualPathProvider GetFile

[英]MVC VirtualPathProvider GetFile not called when app root is different

我将所有视图,脚本,样式编译为不同DLL中的嵌入式资源。 我使用VirtualPathProvider来获取文件。 放置在网站根目录-> www.XXX.com中的网站运行良好

问题是当我将网站放置到www.XXX.com/YYY时,它检查VirtualPathProvider中的文件是否存在,是的,找到了我的文件。 我的返回视图的控制器函数被调用,但未调用VirtualPathProvider中的GetFile,并且网站显示错误404。

路由:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(name: "Default", namespaces: new[] {"Merz.Ems.Core.Controllers"},
        url: "{controller}/{action}", defaults: new {controller = "Index", action = "Index"});

    routes.Add(new Route("Resources/{*url}", new EmbeddedResourceRouteHandler()));
}

EmbeddedResourceRouteHandler处理脚本和样式。

VirtualPathProvider:

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

namespace Merz.Ems.Core.VirtualProviders
{
public class EmbeddedVirtualPathProvider : VirtualPathProvider
{
    public class EmbeddedVirtualFile : VirtualFile
    {
        private Stream _stream;

        public EmbeddedVirtualFile(string virtualPath, Stream stream) : base(virtualPath)
        {
            if (null == stream) throw new ArgumentNullException("stream");
            _stream = stream;
        }

        public override Stream Open()
        {
            return _stream;
        }
    }

    public override CacheDependency GetCacheDependency(string virtualPath,IEnumerable virtualPathDependencies,DateTime utcStart)
    {
        string embedded = _GetEmbeddedPath(virtualPath);

        try
        {
            if (string.IsNullOrEmpty(embedded))
                return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
        }
        catch
        {
            // ignored
        }

        return null;
    }

    public override bool FileExists(string virtualPath)
    {
        string embedded = _GetEmbeddedPath(virtualPath);
        bool reallyExists = File.Exists(HttpContext.Current.Server.MapPath(virtualPath));

        return reallyExists || base.FileExists(virtualPath) || !string.IsNullOrEmpty(embedded);
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        string embedded = _GetEmbeddedPath(virtualPath);
        if (string.IsNullOrEmpty(embedded))
        {
            if (base.FileExists(virtualPath)) return base.GetFile(virtualPath);
            else
            {
                var path = HttpContext.Current.Server.MapPath(virtualPath);
                if (File.Exists(path))
                {
                    Stream s = File.OpenRead(path);
                    return new EmbeddedVirtualFile(virtualPath, s);
                }
            }
        }

        return new EmbeddedVirtualFile(virtualPath,GetType().Assembly.GetManifestResourceStream(embedded));
    }

    private string _GetEmbeddedPath(string path)
    {
        if (path.StartsWith("~/")) path = path.Substring(1);

        path = path.ToLowerInvariant();
        path = "Merz.Ems.Core" + path.Replace('/', '.');
        return GetType().Assembly.GetManifestResourceNames().FirstOrDefault(o => o.Equals(path, StringComparison.OrdinalIgnoreCase));
    }
}

那么,如果我的网页是从www.xxx.com而不是www.xxx.com/yyy运行的,那为什么能正常工作呢? (yyy是应用程序的根)

谢谢 :)

几个小时后,我解决了我的问题。

    private string _GetEmbeddedPath(string path)
    {
        if (path.StartsWith("~/")) path = path.Substring(1);

        if (HostingEnvironment.ApplicationVirtualPath != null)
        {
            if (path.StartsWith(HostingEnvironment.ApplicationVirtualPath)) path = path.Substring(HostingEnvironment.ApplicationVirtualPath.Length);
        }

        path = path.ToLowerInvariant();
        path = "Merz.Ems.Core" + path.Replace('/', '.');
        return GetType().Assembly.GetManifestResourceNames().FirstOrDefault(o => o.Equals(path, StringComparison.OrdinalIgnoreCase));
    }

在此功能中,我添加了

if (HostingEnvironment.ApplicationVirtualPath != null)
{
      if (path.StartsWith(HostingEnvironment.ApplicationVirtualPath)) path = path.Substring(HostingEnvironment.ApplicationVirtualPath.Length);
}

删除子文件夹,以便它找到文件没有任何问题。 我的第一次尝试是从FileExists函数的虚拟路径中过滤子文件夹,这是不好的方法。 为什么呢 谁知道。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM