c#动态添加<% Code %>到aspx页或ascx控件

本文关键字:aspx 页或 ascx 控件 Code 动态 添加 | 更新日期: 2023-09-27 17:54:47

是否有一种方法可以在运行时将<%%>块添加到页面或控件中,或者执行代码块并将结果插入控件/页面中?

这是专门为c# ASP.net编译的web应用程序Framework 4.5编写的如果没有,是否有另一种方法可以达到同样的效果?我希望用户能够添加简单的东西,而无需编辑ascx或aspx页面。

c#动态添加<% Code %>到aspx页或ascx控件

也许最简单的方法是在运行时在某个临时目录中创建.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);
    }
}

}