Loading ASCX control created dynamically (via code)

◇◆丶佛笑我妖孽 提交于 2020-01-03 13:31:24

问题


I am creating Web User Controls via code (my C# code write-out markup, code-behind and designer files to disk on a callback). The controls are created all fine. I can add them to my web-project and put them on a page.

When I try to load the control using LoadControl(path) it says:

Unable to load type 'MyNameSpace.UseControlClass'

which is because control is not yet compiled.

But my requirement is to load controls dynamically without recompiling the solution.

How can I compile the user control only when I create the control files? As this seems to be the only way out.

EDIT:- What my guess is that as the file is not compiled yet it is not allowed to be loaded by runtime. I have tried to compile the code file using CodeDom compiler. Like:

var filePath = Server.MapPath(path);
var provider = CSharpCodeProvider.CreateProvider("C#");
var opts = new CompilerParameters(new[] { "mscorlib.dll", "System.Web.dll", 
                              "Telerik.Web.Design.dll", "Telerik.Web.UI.dll", 
                              "Telerik.Web.UI.Skins.dll", "MyCurrentDll.dll"});
opts.GenerateExecutable = false;
opts.GenerateInMemory = true;
var cr = provider.CompileAssemblyFromFile(opts, new string[] { filePath+".cs" });

But it complains about cannot find metadata file Telerik.Web.Design.dll etc. I don't want to hardcode the telerik path as it might be different in hosted system (though it is in the bin of current web app). Also MyCurrentDll.dll is the dll of the file from which I'm compiling the code file. How can I resolve this?

My idea is to compile the code file create a dll dynamically and copy it to web application's bin directory. It might solve the problem I originally stated.

EDIT 2:- After hit and trial I am able to compile the code file dynamically and generate the dll. Even after generating dll and placing it into bin of my application I am not able to load user control using virtual path. I have tried the following approach:

var asm = Assembly.Load("ddlPath");
var t = asm.GetType(fullTypeName);//NameSpace.Class
var ctrl = LoadControl(t,null);

The ctrl is loaded after this. I assign its Id property and add it to an asp.net Panel control. But it is not visible after the postback :(

Now I either have to make somehow the dynamically compiled dll's types available to the runtime (appdomain, maybe) so that when I load control using virtual path it is properly loaded and I don't get HtmlParseException or figure out why loading control form Type is not showing up.

PS:- I have loaded a Label control using Type and it is working properly.


回答1:


In the end I was able to resolve the problem. Following is the strategy I adopted:

  1. Create text files containing structure of CodeBehind, Markup and Designer code
  2. Read the information as to what fields to create.
  3. Put markup for controls needed in string builders.
  4. put some other related information into more string builders
  5. Write files

After this I created the dll using CodeDome compiler. The main problem faced during compilation, as described in Edit part of question, was not finding referenced assemblies, which was resolved by putting path of bin directory's path along with dll file name like:

Server.MapPath("~/bin")+"\\Telerik.Web.dll"

etc.

Next problem outlined in EDIT2 was bit simpler. There was rather moronic. There was some problem in another user control embedded in dynamically generated user control.

Even after this i was not able to load the control into the page from where I compiled the code. This was resolved when I loaded the control in another page. The runtime was able to resolve the type from dynamically compiled dll.




回答2:


hmm.. have you considered using App_Code folder for this purpose?

Contains source code for shared classes and business objects (for example, ..cs, and .vb files) that you want to compile as part of your application. In a dynamically compiled Web site project, ASP.NET compiles the code in the App_Code folder on the initial request to your application. Items in this folder are then recompiled when any changes are detected.



来源:https://stackoverflow.com/questions/10223752/loading-ascx-control-created-dynamically-via-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!