检查预编译的asp.net网站中是否存在ascx控件

问题描述 投票:0回答:4

我想在打开之前检查ASCX文件是否存在,因为它是动态加载的。使用以下代码应该很容易:System.IO.File.Exists(Server.MapPath(controlPath))。但这在预编译的网站中不起作用,因为ASCX文件不再存在。

任何帮助将不胜感激。

更新:我预编译了一个没有“允许预编译的站点可更新”选项的网站。

asp.net web precompiled
4个回答
0
投票

File.Exists不起作用,因为当预编译.ascx时,它不会物理存在于磁盘上。

HostingEnvironment.VirtualPathProvider.FileExists也不能正常工作,默认实现是MapPathBasedVirtualPathProvider,它希望文件实际存在于磁盘上。

在这种情况下,TemplateControl.LoadControl使用已经缓存了这些虚拟文件的BuildManager,因此不会检查它们的物理存在。

使用反射,可以检查这些文件是否被缓存(读取:存在):

public static bool IsPrecompiledFileExists(string virtualPath)
{
    Type virtualPathType = BuildManager.GetType("System.Web.VirtualPath", true);
    MethodInfo createMethodInfo = virtualPathType.GetMethod("Create", new Type[] {typeof(string)});
    object virtualPathObject = createMethodInfo.Invoke(null, new object[] { virtualPath });

    MethodInfo getVPathBuildResultFromCacheMethodInfo = typeof(BuildManager).GetMethod("GetVPathBuildResultFromCache", BindingFlags.Static | BindingFlags.NonPublic);
    object buildResult = getVPathBuildResultFromCacheMethodInfo.Invoke(null, new object[] { virtualPathObject });
    return buildResult != null;
}

要使解决方案与其他部署方案兼容,您可能希望使用:

public static bool IsVirtualFileExists(string virtualPath)
{
    return HostingEnvironment.VirtualPathProvider.FileExists(virtualPath) ||
           IsPrecompiledFileExists(virtualPath);
}

编辑:Peter Blum有一个更好,更快的解决方案。

附:对于.Net Framework 2.0,也可以使用BuildManager.CreateInstanceFromVirtualPath(我们可以根据抛出的异常了解文件是否存在)。


-1
投票

有时您需要检查用户控件是否存在,然后再将其动态加载到页面。以下是实现此目的的两种方法:

using System.Web.Hosting;
...

string virtualPath = "MyControl.ascx";
// or: "controls/MyControl.ascx"
// or: "../controls/MyControl.ascx"
// or: "~/controls/MyControl.ascx"

if (HostingEnvironment.VirtualPathProvider.FileExists(virtualPath))
{
Control control = LoadControl(virtualPath);
...
}

using System.IO;
...

string virtualPath = "MyControl.ascx";
// or: "controls/MyControl.ascx"
// or: "../controls/MyControl.ascx"
// or: "~/controls/MyControl.ascx"

if (File.Exists(Server.MapPath(virtualPath)))
{
Control control = LoadControl(virtualPath);
 ...
}

-1
投票
 string ucName = "MyUC.ascx";
 if(File.Exists(Server.MapPath("/NameProject/" + (ucName))))
      controlToLoad = ucName;
LoadControl(controlToLoad);

为我工作=))


-2
投票

System.IO.File.Exists(Server.MapPath(path))应该可以解决问题。正如@Leo在你的评论中所说。 ascx是一个在aspx页面中使用的自定义用户控件,在部署项目时它们仍位于同一位置。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.