![](/img/trans.png)
[英]Why MVC 5 does not call GetFile Method of my VirtualPathProvider Class?
[英]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.