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

时间:2014-11-12 07:29:17

标签: asp.net web precompiled

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

任何帮助将不胜感激。

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

4 个答案:

答案 0 :(得分: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有更好更快的解决方案。

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

答案 1 :(得分:-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);
 ...
}

答案 2 :(得分:-1)

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

为我工作=))

答案 3 :(得分:-2)

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