2016-07-03 16 views
1

<%%>ブロックをページまたはコントロールに実行時に追加するか、コードブロックを実行してコントロール/ページに挿入する方法はありますか?C#動的に<% Code %>をaspxページまたはascxコントロールに追加します

これは特にC#ASP.netコンパイル済みWebアプリケーションフレームワークのためです4.5 そうでない場合は、これを行う別の方法がありますか? ユーザーはascxまたはaspxページを編集せずに単純なものを追加できます。

+1

の下には、ユーザーが実際にC#のコードを入力することはできますか? – usr

+0

私は、データベースに格納されているテンプレートにユーザがc#コードを入力してから、テンプレートがレンダリングされたときにそのテンプレートを実行させる必要があります。例えば、質問が表示されませんでしたが、私はそれらに "Response.write(DateTime.Now)"のようなものを追加できるようにします – Tyrone

答えて

1

おそらく最も簡単な方法は、.ascxファイルを実行時にいくつかの一時ディレクトリに作成することです。次に、(Html.RenderPartialまたは他の同様の方法で)これらのファイルを参照できます。これは、実行時にコンパイルを起動し、あなたのためにすべての作業を行う必要があります。

また、この機能を使用すると、データベースアクセスなど、サーバー上で任意のコードを実行する権限がユーザーに与えられます。

+0

そのWebFormsアプリケーションではありませんので、html.RenderPartialはありませんが、LoadControlについても同じことができます。この方法を避けることを望んでいました。ユーザーが50個のコードブロックをページに追加した場合、50個のユーザーコントロールを作成して読み込む必要があります。それは非常に効率的ではありません。また、既存のページ上のすべてのオブジェクトを各ユーザーコントロールに渡してアクセスできるようにする必要があります。何らかの形でロードするか、コントロールコレクションに追加する前に、既存のページ/コントロールに<%%>ブロックを挿入する方法がいくつかあると考えていました。 – Tyrone

+0

実行するコードブロックを指定する巨大なスイッチで1つのコントロールを生成できます。その後、同じコントロールを50回呼び出すことができます。 50個のコントロールよりもはるかに安くなければならない。 – usr

+0

C#コードをコンパイルする必要があるため、これを回避する方法はありません。 .NETには "eval"はありません。あなたはRoslynを試すことができますが、RoslynはASPXをサポートしていません。したがって、ユーザーが入力するコードは通常のC#コードでなければなりません。 – usr

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); 
    } 
} 

}

関連する問題