c#动态添加<% Code %>到aspx页或ascx控件
本文关键字:aspx 页或 ascx 控件 Code 动态 添加 | 更新日期: 2023-09-27 17:54:47
是否有一种方法可以在运行时将<%%>块添加到页面或控件中,或者执行代码块并将结果插入控件/页面中?
这是专门为c# ASP.net编译的web应用程序Framework 4.5编写的如果没有,是否有另一种方法可以达到同样的效果?我希望用户能够添加简单的东西,而无需编辑ascx或aspx页面。
。
也许最简单的方法是在运行时在某个临时目录中创建.ascx
文件。然后,您可以使用(Html.RenderPartial
或任何其他类似的方式)引用这些文件。这将在运行时触发编译,并且几乎所有的工作都应该为您完成。
另外,重要的是要认识到,这种能力使用户能够在您的服务器上运行任意代码,包括数据库访问。
不确定下面的代码有多高效,但似乎不需要将ascx写入硬盘就可以工作。
将代码添加到VirtualCompiler中,并使用唯一的名称和代码作为参数。
VirtualCompiler.Add("MyName", @"<%@ Control Language='"C#'" AutoEventWireup='"false'" CodeBehind='"...'" Inherits='"...'" %>'r'n<% Response.Write(DateTime.Now);'r'n%>");
然后加载控件:
Page.Controls.Add(Page.LoadControl("~/DynamicCode/MyName.ascx"));
下面的类
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;
namespace Admin.UI.Utility
{
public class VirtualCompiler
{
protected static Dictionary<String, String> _code = new Dictionary<String, String>();
public static void Add(String Name, String Code)
{
Name = Name.ToUpper();
if (_code.ContainsKey(Name))
_code.Remove(Name);
_code.Add(Name, Code);
}
public static String Get(String Name)
{
Name = Name.ToUpper();
if (_code.ContainsKey(Name))
return _code[Name];
return String.Empty;
}
public static Boolean Exists(String Name)
{
Name = Name.ToUpper();
return _code.ContainsKey(Name);
}
}
public class VirtualControl : VirtualFile
{
public String WebControlContent = String.Empty;
public VirtualControl(String VirtualPath)
: base(VirtualPath)
{
int ndx = VirtualPath.LastIndexOf("/");
String filename = ndx >= 0 ? VirtualPath.Substring(ndx + 1) : VirtualPath;
WebControlContent = VirtualCompiler.Get(filename);
}
public override System.IO.Stream Open()
{
MemoryStream ms = new MemoryStream();
if (!String.IsNullOrWhiteSpace(WebControlContent))
{
byte[] data = System.Text.ASCIIEncoding.ASCII.
GetBytes(WebControlContent);
ms.Write(data, 0, data.Length);
}
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
}
public class VirtualControlProvider : VirtualPathProvider
{
public static void AppInitialize()
{
VirtualControlProvider db = new VirtualControlProvider();
System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(db);
}
public override CacheDependency GetCacheDependency(string VirtualPath, IEnumerable VirtualPathDependencies, DateTime UTCStart)
{
return IsPathVirtual(VirtualPath) ? null : base.GetCacheDependency(VirtualPath, VirtualPathDependencies, UTCStart);
}
private bool IsPathVirtual(string VirtualPath)
{
String checkPath = VirtualPathUtility.ToAppRelative(VirtualPath);
return checkPath.StartsWith("~/DynamicCode/".ToLower().ToString(), StringComparison.InvariantCultureIgnoreCase);
}
public override bool FileExists(String VirtualPath)
{
if (IsPathVirtual(VirtualPath))
{
VirtualControl file = (VirtualControl)GetFile(VirtualPath);
// Determine whether the file exists on the virtual file
// system.
if (file != null && !String.IsNullOrWhiteSpace(file.WebControlContent))
return true;
else
return Previous.FileExists(VirtualPath);
}
else
return Previous.FileExists(VirtualPath);
}
public override VirtualFile GetFile(String VirtualPath)
{
if (IsPathVirtual(VirtualPath))
{
return new VirtualControl(VirtualPath);
}
else
return Previous.GetFile(VirtualPath);
}
}
}