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

时间:2016-07-03 16:10:59

标签: c# asp.net

有没有办法添加< %%>在运行时阻止页面或控件或执行代码块并将结果插入控件/页面?

这是专门针对C#ASP.net编译的Web应用程序框架4.5 如果没有,是否有另一种方法可以实现这一目标? 我希望用户能够在不编辑ascx或aspx页面的情况下添加简单的东西。

e.g。

2 个答案:

答案 0 :(得分:1)

也许最简单的方法是在运行时在某个临时目录中创建.ascx个文件。然后,您可以使用(Html.RenderPartial或任何其他类似方式)引用这些文件。这将在运行时触发编译,几乎所有的工作都应该为你完成。

此外,重要的是要意识到这种能力使用户能够在服务器上运行任意代码,包括数据库访问。

答案 1 :(得分:0)

不确定下面的效率如何,但似乎无需将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);
    }
}

}