c# - MVC VirtualPathProvider GetFile not called when app root is different -
i have views, scripts, styles compiled embedded resource in different dll. iam using virtualpathprovider file. web running fine when it's places in web root -> www.xxx.com
the problem when place website www.xxx.com/yyy checks files in virtualpathprovider if exist , yes, files found. controller function returns view called, getfile in virtualpathprovider not called , website says error 404.
routing:
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())); }
the embeddedresourceroutehandler handles scripts , styles.
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)); } }
so, why it's working if page runs www.xxx.com , not www.xxx.com/yyy ? (yyy root of application )
thanks :)
i solved problem after lot of hours.
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)); }
in function, added
if (hostingenvironment.applicationvirtualpath != null) { if (path.startswith(hostingenvironment.applicationvirtualpath)) path = path.substring(hostingenvironment.applicationvirtualpath.length); }
to remove subfolder, finds file without problem. first attempt filter subfolder virtual path in fileexists function , bad way. why ? knows.
Comments
Post a Comment